mirror of
https://github.com/Spythere/pojazdownik.git
synced 2026-05-03 11:45:34 +00:00
feature: generator nr pociągi
This commit is contained in:
@@ -85,7 +85,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input_actions">
|
<div class="input_actions">
|
||||||
<button class="btn" @click="addVehicle">DODAJ NOWY</button>
|
<button class="btn" @click="addVehicle(store.chosenVehicle, store.chosenCargo)">DODAJ NOWY</button>
|
||||||
<button
|
<button
|
||||||
class="btn"
|
class="btn"
|
||||||
@click="switchVehicles"
|
@click="switchVehicles"
|
||||||
@@ -112,6 +112,7 @@ import imageMixin from '../mixins/imageMixin';
|
|||||||
import { useStore } from '../store';
|
import { useStore } from '../store';
|
||||||
import { isLocomotive } from '../utils/vehicleUtils';
|
import { isLocomotive } from '../utils/vehicleUtils';
|
||||||
import stockPreviewMixin from '../mixins/stockPreviewMixin';
|
import stockPreviewMixin from '../mixins/stockPreviewMixin';
|
||||||
|
import stockMixin from '../mixins/stockMixin';
|
||||||
|
|
||||||
interface ILocoType {
|
interface ILocoType {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -120,7 +121,7 @@ interface ILocoType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [imageMixin, stockPreviewMixin],
|
mixins: [imageMixin, stockPreviewMixin, stockMixin],
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
locomotiveTypeList: [
|
locomotiveTypeList: [
|
||||||
@@ -174,7 +175,10 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
addOrSwitchVehicle() {
|
addOrSwitchVehicle() {
|
||||||
if (this.store.chosenStockListIndex == -1) this.addVehicle();
|
if(!this.store.chosenVehicle) return;
|
||||||
|
|
||||||
|
if (this.store.chosenStockListIndex == -1)
|
||||||
|
this.addVehicle(this.store.chosenVehicle, this.store.chosenCargo);
|
||||||
else this.switchVehicles();
|
else this.switchVehicles();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -211,50 +215,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
this.store.stockList[this.store.chosenStockListIndex] = stockObj;
|
this.store.stockList[this.store.chosenStockListIndex] = stockObj;
|
||||||
},
|
},
|
||||||
|
|
||||||
addVehicle() {
|
|
||||||
const vehicle = this.store.chosenVehicle;
|
|
||||||
|
|
||||||
if (!vehicle) return;
|
|
||||||
|
|
||||||
const stockObj: IStock = {
|
|
||||||
id: `${Date.now()}`,
|
|
||||||
useType: isLocomotive(vehicle) ? vehicle.power : vehicle.useType,
|
|
||||||
type: vehicle.type,
|
|
||||||
length: vehicle.length,
|
|
||||||
mass: vehicle.mass,
|
|
||||||
maxSpeed: vehicle.maxSpeed,
|
|
||||||
isLoco: isLocomotive(vehicle),
|
|
||||||
cargo:
|
|
||||||
!isLocomotive(vehicle) && vehicle.loadable && this.store.chosenCargo ? this.store.chosenCargo : undefined,
|
|
||||||
count: 1,
|
|
||||||
imgSrc: vehicle.imageSrc,
|
|
||||||
supportersOnly: vehicle.supportersOnly,
|
|
||||||
};
|
|
||||||
|
|
||||||
const previousStock =
|
|
||||||
this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
|
|
||||||
|
|
||||||
if (isLocomotive(vehicle) && previousStock && previousStock.type == vehicle.type) {
|
|
||||||
this.store.stockList[this.store.stockList.length - 1].count++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
!isLocomotive(vehicle) &&
|
|
||||||
previousStock &&
|
|
||||||
previousStock.type == vehicle.type &&
|
|
||||||
previousStock.cargo?.id == this.store.chosenCargo?.id
|
|
||||||
) {
|
|
||||||
this.store.stockList[this.store.stockList.length - 1].count++;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLocomotive(vehicle) && this.store.stockList.length > 0 && !this.store.stockList[0].isLoco)
|
|
||||||
this.store.stockList.unshift(stockObj);
|
|
||||||
else this.store.stockList.push(stockObj);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<div class="number-generator tab">
|
||||||
|
<div class="tab_header">
|
||||||
|
<h2>GENERATOR NUMERU POCIĄGU</h2>
|
||||||
|
<button class="btn" @click="() => (store.stockSectionMode = 'stock-list')">POWRÓT DO LISTY ></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab_content">
|
||||||
|
<div class="options">
|
||||||
|
<select v-model="regionNumbers">
|
||||||
|
<option :value="null" disabled>Obszar konstrukcyjny</option>
|
||||||
|
<option v-for="(nums, name) in genData.regions" :value="nums">{{ name }}</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select v-model="categoryRules">
|
||||||
|
<option :value="null" disabled>Kategoria pociągu</option>
|
||||||
|
<option v-for="(rules, category) in genData.categories" :value="rules">{{ category }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>Wygenerowany numer pociągu: {{ computedNumber }}</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Ref, computed, ref } from 'vue';
|
||||||
|
import { useStore } from '../store';
|
||||||
|
|
||||||
|
import genData from '../constants/numberGeneratorData.json';
|
||||||
|
|
||||||
|
const store = useStore();
|
||||||
|
|
||||||
|
const regionNumbers = ref(null) as Ref<number[] | null>;
|
||||||
|
const categoryRules = ref(null) as Ref<string | null>;
|
||||||
|
|
||||||
|
const computedNumber = computed(() => {
|
||||||
|
if (regionNumbers.value == null || categoryRules.value == null) return '';
|
||||||
|
|
||||||
|
let trainNumber = '';
|
||||||
|
const randRegionNumber = regionNumbers.value[Math.floor(Math.random() * regionNumbers.value.length)];
|
||||||
|
|
||||||
|
trainNumber += randRegionNumber.toString();
|
||||||
|
|
||||||
|
const rulesArray = categoryRules.value.split(';').map((r) => ({
|
||||||
|
index: r.split(':')[0],
|
||||||
|
rule: r.split(':')[1],
|
||||||
|
nums: Number(r.split(':')[2] || '1'),
|
||||||
|
}));
|
||||||
|
|
||||||
|
rulesArray.forEach((r) => {
|
||||||
|
const range = r.rule.split('-');
|
||||||
|
|
||||||
|
if (range.length == 1) trainNumber += r.rule;
|
||||||
|
else {
|
||||||
|
const [minRange, maxRange] = range;
|
||||||
|
const randRange = Math.floor(Math.random() * (Number(maxRange) - Number(minRange)) + Number(minRange)).toString();
|
||||||
|
|
||||||
|
trainNumber += new Array(Math.abs(randRange.length - r.nums)).fill('0').join('') + randRange;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return trainNumber;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../styles/tab.scss';
|
||||||
|
|
||||||
|
.options {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1em;
|
||||||
|
|
||||||
|
select {
|
||||||
|
width: calc(50% - 1em);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="stock-generator">
|
<div class="stock-generator tab">
|
||||||
<div class="stock_actions">
|
<div class="tab_header">
|
||||||
<h2>GENERATOR SKŁADU TOWAROWEGO</h2>
|
<h2>GENERATOR SKŁADU TOWAROWEGO</h2>
|
||||||
<button class="btn" @click="() => (store.stockSectionMode = 'stock-list')">POWRÓT DO LISTY ></button>
|
<button class="btn" @click="() => (store.stockSectionMode = 'stock-list')">POWRÓT DO LISTY ></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="generator_content">
|
<div class="tab_content">
|
||||||
<h2>WŁAŚCIWOŚCI SKŁADU</h2>
|
<h2>WŁAŚCIWOŚCI SKŁADU</h2>
|
||||||
|
|
||||||
<div class="generator_attributes">
|
<div class="tab_attributes">
|
||||||
<label>
|
<label>
|
||||||
Maksymalna masa (t)
|
Maksymalna masa (t)
|
||||||
<input type="number" v-model="maxMass" step="100" max="4000" min="0" />
|
<input type="number" v-model="maxMass" step="100" max="4000" min="0" />
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<h2>WAGONY Z WYBRANYMI ŁADUNKAMI</h2>
|
<h2>WAGONY Z WYBRANYMI ŁADUNKAMI</h2>
|
||||||
|
|
||||||
<div class="warning">
|
<div class="generator_warning">
|
||||||
<span v-if="computedChosenCarTypes.size == 0">
|
<span v-if="computedChosenCarTypes.size == 0">
|
||||||
Wybierz co najmniej jeden ładunek, aby zobaczyć wagony, które go posiadają!
|
Wybierz co najmniej jeden ładunek, aby zobaczyć wagony, które go posiadają!
|
||||||
</span>
|
</span>
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div class="generator_actions">
|
<div class="tab_actions">
|
||||||
<button class="btn" :data-disabled="computedChosenCarTypes.size == 0" @click="generateStock()">
|
<button class="btn" :data-disabled="computedChosenCarTypes.size == 0" @click="generateStock()">
|
||||||
WYGENERUJ
|
WYGENERUJ
|
||||||
</button>
|
</button>
|
||||||
@@ -176,7 +176,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
new Array(this.maxCarCount).fill(0).forEach(() => {
|
new Array(this.maxCarCount).fill(0).forEach(() => {
|
||||||
const randomStockType = generatedChosenStockList[~~(Math.random() * generatedChosenStockList.length)];
|
const randomStockType = generatedChosenStockList[~~(Math.random() * generatedChosenStockList.length)];
|
||||||
const {carWagon, cargo} = randomStockType.carPool[~~(Math.random() * randomStockType.carPool.length)];
|
const { carWagon, cargo } = randomStockType.carPool[~~(Math.random() * randomStockType.carPool.length)];
|
||||||
|
|
||||||
if (this.store.totalMass + (cargo?.totalMass || carWagon.mass) > this.maxMass) return;
|
if (this.store.totalMass + (cargo?.totalMass || carWagon.mass) > this.maxMass) return;
|
||||||
if (this.store.totalLength + carWagon.length > this.maxLength) return;
|
if (this.store.totalLength + carWagon.length > this.maxLength) return;
|
||||||
@@ -227,51 +227,14 @@ export default defineComponent({
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import '../styles/global.scss';
|
@import '../styles/global.scss';
|
||||||
|
@import '../styles/tab.scss';
|
||||||
|
|
||||||
.stock_actions {
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin: 0;
|
|
||||||
color: white;
|
|
||||||
font-size: 1.35em;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stock-generator {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.generator_content {
|
|
||||||
margin-top: 1em;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.generator_attributes {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 1em;
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
max-width: 250px;
|
|
||||||
margin-top: 0.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.generator_cargo,
|
.generator_cargo,
|
||||||
.generator_vehicles {
|
.generator_vehicles {
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -325,24 +288,7 @@ hr {
|
|||||||
margin: 15px 0;
|
margin: 15px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.generator_actions {
|
.generator_warning {
|
||||||
display: grid;
|
|
||||||
gap: 0.5em;
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
|
|
||||||
button {
|
|
||||||
background-color: #131313;
|
|
||||||
|
|
||||||
padding: 0.5em;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-disabled] button {
|
|
||||||
opacity: 0.75;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.warning {
|
|
||||||
background-color: $accentColor;
|
background-color: $accentColor;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
text-align: justify;
|
text-align: justify;
|
||||||
@@ -355,17 +301,6 @@ hr {
|
|||||||
.generator_vehicles {
|
.generator_vehicles {
|
||||||
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
.generator_attributes {
|
|
||||||
label {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
max-width: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
+18
-104
@@ -12,37 +12,6 @@
|
|||||||
POJAZD NR <span class="text--accent">{{ store.chosenStockListIndex + 1 }}</span>
|
POJAZD NR <span class="text--accent">{{ store.chosenStockListIndex + 1 }}</span>
|
||||||
</b>
|
</b>
|
||||||
|
|
||||||
<div class="count">
|
|
||||||
<button
|
|
||||||
class="btn action-btn"
|
|
||||||
:tabindex="store.chosenStockListIndex == -1 ? -1 : 0"
|
|
||||||
@click="subStock(store.chosenStockListIndex)"
|
|
||||||
>
|
|
||||||
<img :src="getIconURL('sub')" alt="subtract vehicle count" />
|
|
||||||
1
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<input
|
|
||||||
v-if="chosenStockVehicle"
|
|
||||||
v-model="chosenStockVehicle.count"
|
|
||||||
type="number"
|
|
||||||
min="1"
|
|
||||||
name="stock-count"
|
|
||||||
id="stock-count"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<input v-else id="stock-count" type="number" value="0" :tabindex="store.chosenStockListIndex == -1 ? -1 : 0" />
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="btn action-btn"
|
|
||||||
:tabindex="store.chosenStockListIndex == -1 ? -1 : 0"
|
|
||||||
@click="addStock(store.chosenStockListIndex)"
|
|
||||||
>
|
|
||||||
<img :src="getIconURL('add')" alt="add vehicle count" />
|
|
||||||
1
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn action-btn"
|
class="btn action-btn"
|
||||||
:tabindex="store.chosenStockListIndex == -1 ? -1 : 0"
|
:tabindex="store.chosenStockListIndex == -1 ? -1 : 0"
|
||||||
@@ -71,8 +40,12 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stock_clipboard-text" v-if="store.stockList.length > 0">
|
<div class="stock_additional">
|
||||||
<button class="btn" @click="copyToClipboard">Skopiuj tekst składu do schowka</button>
|
<button class="btn" v-if="store.stockList.length > 0" @click="copyToClipboard">
|
||||||
|
Skopiuj tekst składu do schowka
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="btn" v-if="store.stockList[0]?.isLoco">Wygeneruj numer pociągu</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stock_specs">
|
<div class="stock_specs">
|
||||||
@@ -117,20 +90,7 @@
|
|||||||
<div class="warning" v-if="tooManyLocomotives">Ten skład posiada za dużo pojazdów trakcyjnych!</div>
|
<div class="warning" v-if="tooManyLocomotives">Ten skład posiada za dużo pojazdów trakcyjnych!</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stock_thumbnails" ref="thumbnails">
|
<StockThumbnails :onListItemClick="onListItemClick" :onStockImageError="stockImageError" />
|
||||||
<div v-for="(stock, stockIndex) in store.stockList" :data-selected="store.chosenStockListIndex == stockIndex">
|
|
||||||
<span v-for="i in stock.count" @click="onListItemClick(stockIndex)" :key="stock.id">
|
|
||||||
<b>{{ stock.type }}</b>
|
|
||||||
|
|
||||||
<img
|
|
||||||
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${stock.type}.png`"
|
|
||||||
:alt="stock.type"
|
|
||||||
:title="stock.type"
|
|
||||||
@error="stockImageError($event, stock)"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Stock list -->
|
<!-- Stock list -->
|
||||||
<ul ref="list">
|
<ul ref="list">
|
||||||
@@ -138,7 +98,7 @@
|
|||||||
<div class="stock-info">Lista pojazdów jest pusta!</div>
|
<div class="stock-info">Lista pojazdów jest pusta!</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<transition-group name="stock-list-anim">
|
<TransitionGroup name="stock-list-anim">
|
||||||
<li
|
<li
|
||||||
v-for="(stock, i) in store.stockList"
|
v-for="(stock, i) in store.stockList"
|
||||||
:key="stock.id"
|
:key="stock.id"
|
||||||
@@ -171,11 +131,9 @@
|
|||||||
<span class="stock-info__length"> {{ stock.length }}m </span>
|
<span class="stock-info__length"> {{ stock.length }}m </span>
|
||||||
<span class="stock-info__mass">{{ stock.cargo ? stock.cargo.totalMass : stock.mass }}t </span>
|
<span class="stock-info__mass">{{ stock.cargo ? stock.cargo.totalMass : stock.mass }}t </span>
|
||||||
<span class="stock-info__speed"> {{ stock.maxSpeed }}km/h </span>
|
<span class="stock-info__speed"> {{ stock.maxSpeed }}km/h </span>
|
||||||
|
|
||||||
<span class="stock-info__count"> x{{ stock.count }} </span>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</transition-group>
|
</TransitionGroup>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
@@ -189,10 +147,11 @@ import warningsMixin from '../mixins/warningsMixin';
|
|||||||
import imageMixin from '../mixins/imageMixin';
|
import imageMixin from '../mixins/imageMixin';
|
||||||
import stockPreviewMixin from '../mixins/stockPreviewMixin';
|
import stockPreviewMixin from '../mixins/stockPreviewMixin';
|
||||||
import { IStock } from '../types';
|
import { IStock } from '../types';
|
||||||
|
import StockThumbnails from './StockThumbnails.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'stock-list',
|
name: 'stock-list',
|
||||||
components: { TrainImage },
|
components: { TrainImage, StockThumbnails },
|
||||||
|
|
||||||
mixins: [warningsMixin, imageMixin, stockPreviewMixin],
|
mixins: [warningsMixin, imageMixin, stockPreviewMixin],
|
||||||
|
|
||||||
@@ -210,18 +169,6 @@ export default defineComponent({
|
|||||||
draggedVehicleID: -1,
|
draggedVehicleID: -1,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
watch: {
|
|
||||||
'store.chosenStockListIndex': {
|
|
||||||
handler(id: number) {
|
|
||||||
if (id < 0) return;
|
|
||||||
|
|
||||||
(this.$refs['thumbnails'] as HTMLElement)
|
|
||||||
.querySelector(`div:nth-child(${id + 1})`)
|
|
||||||
?.scrollIntoView({ block: 'nearest', inline: 'start', behavior: 'smooth' });
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
stockString() {
|
stockString() {
|
||||||
return this.store.stockList
|
return this.store.stockList
|
||||||
@@ -470,12 +417,11 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stock_clipboard-text {
|
.stock_additional {
|
||||||
font-weight: bold;
|
display: flex;
|
||||||
|
gap: 0.5em;
|
||||||
|
|
||||||
& > .btn {
|
margin: 0.5em 0;
|
||||||
margin: 0 0.5em 0.5em 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.real-stock-info {
|
.real-stock-info {
|
||||||
@@ -509,7 +455,8 @@ ul > li {
|
|||||||
|
|
||||||
&.list-empty {
|
&.list-empty {
|
||||||
background-color: $secondaryColor;
|
background-color: $secondaryColor;
|
||||||
padding: 0.5em;
|
border-radius: 0.5em;
|
||||||
|
padding: 0.75em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,7 +479,7 @@ li > .stock-info {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.stock_warnings {
|
.stock_warnings {
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stock-info {
|
.stock-info {
|
||||||
@@ -586,39 +533,6 @@ li > .stock-info {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stock_thumbnails {
|
|
||||||
display: flex;
|
|
||||||
margin: 1em 0;
|
|
||||||
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
background-color: #353a57;
|
|
||||||
|
|
||||||
div {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
|
|
||||||
&[data-selected='true'] {
|
|
||||||
background-color: rebeccapurple;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 0.5em;
|
|
||||||
padding: 0.5em 0;
|
|
||||||
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
font-size: 0.85em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-height: 60px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: $breakpointMd) {
|
@media screen and (max-width: $breakpointMd) {
|
||||||
ul {
|
ul {
|
||||||
min-height: auto;
|
min-height: auto;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { defineComponent } from 'vue';
|
|||||||
import { useStore } from '../store';
|
import { useStore } from '../store';
|
||||||
import StockListTab from './StockListTab.vue';
|
import StockListTab from './StockListTab.vue';
|
||||||
import StockGeneratorTab from './StockGeneratorTab.vue';
|
import StockGeneratorTab from './StockGeneratorTab.vue';
|
||||||
|
import NumberGeneratorTab from './NumberGeneratorTab.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
@@ -30,6 +31,9 @@ export default defineComponent({
|
|||||||
case 'stock-generator':
|
case 'stock-generator':
|
||||||
return StockGeneratorTab;
|
return StockGeneratorTab;
|
||||||
|
|
||||||
|
case 'number-generator':
|
||||||
|
return NumberGeneratorTab;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return StockListTab;
|
return StockListTab;
|
||||||
}
|
}
|
||||||
@@ -57,6 +61,8 @@ export default defineComponent({
|
|||||||
grid-row: 1 / 4;
|
grid-row: 1 / 4;
|
||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
|
|
||||||
|
padding: 0 1px;
|
||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
<template>
|
||||||
|
<div class="stock_thumbnails" ref="thumbnailsRef">
|
||||||
|
<div
|
||||||
|
v-for="(stock, stockIndex) in store.stockList"
|
||||||
|
:data-selected="store.chosenStockListIndex == stockIndex"
|
||||||
|
draggable="true"
|
||||||
|
@dragstart="onDragStart(stockIndex)"
|
||||||
|
@drop="onDrop($event, stockIndex)"
|
||||||
|
@dragover="allowDrop"
|
||||||
|
>
|
||||||
|
<span @click="onListItemClick(stockIndex)" :key="stock.id">
|
||||||
|
<b>
|
||||||
|
{{ stock.type }}
|
||||||
|
</b>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
<img
|
||||||
|
draggable="false"
|
||||||
|
:src="`https://rj.td2.info.pl/dist/img/thumbnails/${stock.type}.png`"
|
||||||
|
:alt="stock.type"
|
||||||
|
:title="stock.type"
|
||||||
|
@error="stockImageError($event, stock)"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Ref, computed, nextTick, ref, watch } from 'vue';
|
||||||
|
import { useStore } from '../store';
|
||||||
|
import { IStock } from '../types';
|
||||||
|
|
||||||
|
const store = useStore();
|
||||||
|
const emit = defineEmits(['listItemClick', 'stockImageError']);
|
||||||
|
|
||||||
|
const thumbnailsRef = ref() as Ref<HTMLElement>;
|
||||||
|
const draggedIndex = ref(-1);
|
||||||
|
|
||||||
|
const onListItemClick = (index: number) => {
|
||||||
|
emit('listItemClick', index);
|
||||||
|
};
|
||||||
|
|
||||||
|
const stockImageError = (e: Event, stock: IStock) => {
|
||||||
|
console.log('error');
|
||||||
|
|
||||||
|
emit('stockImageError', e, stock);
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
computed(() => store.chosenStockListIndex),
|
||||||
|
(index) => {
|
||||||
|
if (index < 0) return;
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
(thumbnailsRef.value as HTMLElement)
|
||||||
|
.querySelector(`div:nth-child(${index + 1})`)
|
||||||
|
?.scrollIntoView({ block: 'nearest', inline: 'start', behavior: 'smooth' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Dragging images
|
||||||
|
const onDragStart = (vehicleIndex: number) => {
|
||||||
|
draggedIndex.value = vehicleIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDrop = (e: DragEvent, vehicleIndex: number) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
let targetEl = thumbnailsRef.value.querySelector(`div:nth-child(${vehicleIndex + 1})`);
|
||||||
|
|
||||||
|
if (!targetEl && draggedIndex.value != -1) return;
|
||||||
|
|
||||||
|
const tempVehicle = store.stockList[vehicleIndex];
|
||||||
|
store.stockList[vehicleIndex] = store.stockList[draggedIndex.value];
|
||||||
|
store.stockList[draggedIndex.value] = tempVehicle;
|
||||||
|
|
||||||
|
store.chosenStockListIndex = vehicleIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
const allowDrop = (e: DragEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.stock_thumbnails {
|
||||||
|
display: flex;
|
||||||
|
margin: 1em 0;
|
||||||
|
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
background-color: #353a57;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&[data-selected='true'] {
|
||||||
|
background-color: rebeccapurple;
|
||||||
|
}
|
||||||
|
|
||||||
|
> span {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5em;
|
||||||
|
padding: 0.5em 0;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
font-size: 0.85em;
|
||||||
|
user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-height: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
@@ -41,18 +41,18 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { Vehicle, IStock, IReadyStockList } from '../../types';
|
import { Vehicle, IReadyStockList } from '../../types';
|
||||||
|
|
||||||
import { useStore } from '../../store';
|
import { useStore } from '../../store';
|
||||||
import { isLocomotive } from '../../utils/vehicleUtils';
|
|
||||||
import imageMixin from '../../mixins/imageMixin';
|
import imageMixin from '../../mixins/imageMixin';
|
||||||
|
import stockMixin from '../../mixins/stockMixin';
|
||||||
|
|
||||||
interface ResponseJSONData {
|
interface ResponseJSONData {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [imageMixin],
|
mixins: [imageMixin, stockMixin],
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
@@ -109,34 +109,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
this.store.isRealStockListCardOpen = false;
|
this.store.isRealStockListCardOpen = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
addVehicle(vehicle: Vehicle | null) {
|
|
||||||
if (!vehicle) return;
|
|
||||||
|
|
||||||
const stockObj: IStock = {
|
|
||||||
id: `${Date.now() + this.store.stockList.length}`,
|
|
||||||
type: vehicle.type,
|
|
||||||
length: vehicle.length,
|
|
||||||
mass: vehicle.mass,
|
|
||||||
maxSpeed: vehicle.maxSpeed,
|
|
||||||
isLoco: isLocomotive(vehicle),
|
|
||||||
cargo: undefined,
|
|
||||||
count: 1,
|
|
||||||
imgSrc: vehicle.imageSrc,
|
|
||||||
useType: isLocomotive(vehicle) ? vehicle.power : vehicle.useType,
|
|
||||||
supportersOnly: vehicle.supportersOnly,
|
|
||||||
};
|
|
||||||
|
|
||||||
const previousStock =
|
|
||||||
this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
|
|
||||||
|
|
||||||
if (previousStock && previousStock.type == vehicle.type) {
|
|
||||||
this.store.stockList[this.store.stockList.length - 1].count++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.store.stockList.push(stockObj);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async mounted() {
|
async mounted() {
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"regions": {
|
||||||
|
"Losowy": [
|
||||||
|
10, 11, 19, 91, 93, 97, 99, 20, 22, 29, 30, 33, 39, 40, 44, 49, 94, 50, 55, 59, 90, 95, 96, 66, 60, 69, 77, 70,
|
||||||
|
79, 88, 80, 89, 92, 98
|
||||||
|
],
|
||||||
|
"Warszawa": [10, 11, 19, 91, 93, 97, 99],
|
||||||
|
"Lublin": [20, 22, 29],
|
||||||
|
"Kraków": [30, 33, 39],
|
||||||
|
"Sosnowiec": [40, 44, 49, 94],
|
||||||
|
"Gdańsk": [50, 55, 59, 90, 95, 96],
|
||||||
|
"Wrocław": [66, 60, 69],
|
||||||
|
"Poznań": [77, 70, 79],
|
||||||
|
"Szczecin": [88, 80],
|
||||||
|
"Rezerwa": [89, 92, 98]
|
||||||
|
},
|
||||||
|
"categories": {
|
||||||
|
"ekspres krajowy (EI)": "2:00-99:2",
|
||||||
|
"międzywojewódzki pośpieszny (MP)": "2:050-169:3",
|
||||||
|
"wojewódzki pośpieszny (RP)": "2:050-169:3",
|
||||||
|
"wojewódzki osobowy (RO)": "2:200-999:3",
|
||||||
|
"próżny \"służbowy\" (PW)": "2:6;3:0-899:3",
|
||||||
|
"towarowy do przewozów masowych (TM)": "2:4;3:0-899:3",
|
||||||
|
"towarowy do obsługi stacji (TK)": "2:3;3:0-899:3",
|
||||||
|
"lokomotywa luzem (LT)": "2:5;3:0-899:3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"EU07": {
|
||||||
|
"passenger": {
|
||||||
|
"650": 125
|
||||||
|
},
|
||||||
|
"cargo": {
|
||||||
|
"2000": 70
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"EP07": {
|
||||||
|
"passenger": {
|
||||||
|
"650": 125
|
||||||
|
},
|
||||||
|
"cargo": null
|
||||||
|
},
|
||||||
|
"EP08": {
|
||||||
|
"passenger": {
|
||||||
|
"650": 140
|
||||||
|
},
|
||||||
|
"cargo": null
|
||||||
|
},
|
||||||
|
"ET41": {
|
||||||
|
"passenger": {
|
||||||
|
"700": 125
|
||||||
|
},
|
||||||
|
"cargo": {
|
||||||
|
"4000": 70
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SM42": {
|
||||||
|
"passenger": {
|
||||||
|
"95": 90,
|
||||||
|
"200": 80,
|
||||||
|
"300": 70,
|
||||||
|
"450": 60,
|
||||||
|
"750": 50,
|
||||||
|
"1130": 40,
|
||||||
|
"1720": 30,
|
||||||
|
"2400": 20
|
||||||
|
},
|
||||||
|
"cargo": {
|
||||||
|
"95": 90,
|
||||||
|
"200": 80,
|
||||||
|
"300": 70,
|
||||||
|
"450": 60,
|
||||||
|
"750": 50,
|
||||||
|
"1130": 40,
|
||||||
|
"1720": 30,
|
||||||
|
"2400": 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+23
-13
@@ -15,7 +15,7 @@ export default defineComponent({
|
|||||||
return `${Math.random().toString(36).slice(5)}`;
|
return `${Math.random().toString(36).slice(5)}`;
|
||||||
},
|
},
|
||||||
|
|
||||||
getStockObject(vehicle: Vehicle, cargo?: ICargo, count = 1): IStock {
|
getStockObject(vehicle: Vehicle, cargo?: ICargo | null, count = 1): IStock {
|
||||||
const isLoco = isLocomotive(vehicle);
|
const isLoco = isLocomotive(vehicle);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -33,13 +33,22 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addVehicle(vehicle: Vehicle | null, cargo?: ICargo | null) {
|
||||||
|
if (!vehicle) return;
|
||||||
|
|
||||||
|
const stock = this.getStockObject(vehicle, cargo);
|
||||||
|
|
||||||
|
if (stock.isLoco && !this.store.stockList[0]?.isLoco) this.store.stockList.unshift(stock);
|
||||||
|
else this.store.stockList.push(stock);
|
||||||
|
},
|
||||||
|
|
||||||
addLocomotive(loco: ILocomotive) {
|
addLocomotive(loco: ILocomotive) {
|
||||||
const previousStock =
|
// const previousStock =
|
||||||
this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
|
// this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
|
||||||
if (previousStock && previousStock.type == loco.type) {
|
// if (previousStock && previousStock.type == loco.type) {
|
||||||
this.store.stockList[this.store.stockList.length - 1].count++;
|
// this.store.stockList[this.store.stockList.length - 1].count++;
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const stockObj = this.getStockObject(loco);
|
const stockObj = this.getStockObject(loco);
|
||||||
|
|
||||||
@@ -48,14 +57,14 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
addCarWagon(car: ICarWagon, cargo?: ICargo) {
|
addCarWagon(car: ICarWagon, cargo?: ICargo) {
|
||||||
const previousStock =
|
// const previousStock =
|
||||||
this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
|
// this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
|
||||||
|
|
||||||
if (previousStock && previousStock.type == car.type && previousStock.cargo?.id == cargo?.id) {
|
// if (previousStock && previousStock.type == car.type && previousStock.cargo?.id == cargo?.id) {
|
||||||
this.store.stockList[this.store.stockList.length - 1].count++;
|
// this.store.stockList[this.store.stockList.length - 1].count++;
|
||||||
|
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const stockObj = this.getStockObject(car, cargo);
|
const stockObj = this.getStockObject(car, cargo);
|
||||||
|
|
||||||
@@ -63,3 +72,4 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ export const useStore = defineStore({
|
|||||||
|
|
||||||
vehiclePreviewSrc: '',
|
vehiclePreviewSrc: '',
|
||||||
|
|
||||||
stockSectionMode: 'stock-list',
|
stockSectionMode: 'number-generator',
|
||||||
|
|
||||||
isRandomizerCardOpen: false,
|
isRandomizerCardOpen: false,
|
||||||
isRealStockListCardOpen: false,
|
isRealStockListCardOpen: false,
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
.tab {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&_header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin: 0;
|
||||||
|
color: white;
|
||||||
|
font-size: 1.35em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_content {
|
||||||
|
margin-top: 1em;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&_attributes {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1em;
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
max-width: 250px;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_actions {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.5em;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: #131313;
|
||||||
|
|
||||||
|
padding: 0.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-disabled] button {
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 470px) {
|
||||||
|
.tab_attributes {
|
||||||
|
label {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
max-width: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+1
-1
@@ -27,7 +27,7 @@ export interface IStore {
|
|||||||
isRandomizerCardOpen: boolean;
|
isRandomizerCardOpen: boolean;
|
||||||
isRealStockListCardOpen: boolean;
|
isRealStockListCardOpen: boolean;
|
||||||
|
|
||||||
stockSectionMode: 'stock-list' | 'stock-generator';
|
stockSectionMode: 'stock-list' | 'stock-generator' | 'number-generator';
|
||||||
stockData?: IStockData;
|
stockData?: IStockData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import speedLimitTable from '../constants/speedLimits.json';
|
||||||
|
export type LocoType = keyof typeof speedLimitTable;
|
||||||
|
|
||||||
|
export const calculateSpeedLimit = (locoType: LocoType, stockMass: number, isTrainPassenger: boolean) => {
|
||||||
|
const speedTable = speedLimitTable[locoType][isTrainPassenger ? 'passenger' : 'cargo'];
|
||||||
|
|
||||||
|
if (!speedTable) return undefined;
|
||||||
|
|
||||||
|
let speedLimit = 0;
|
||||||
|
for (let mass in speedTable) if (stockMass > Number(mass)) speedLimit = (speedTable as any)[mass];
|
||||||
|
|
||||||
|
return speedLimit;
|
||||||
|
};
|
||||||
|
|
||||||
+46
-29
@@ -1,35 +1,36 @@
|
|||||||
import { EVehicleUseType } from '../enums/EVehicleUseType';
|
import { EVehicleUseType } from '../enums/EVehicleUseType';
|
||||||
import { ICarWagon, ILocomotive, IStore, TStockInfoKey } from '../types';
|
import { ICarWagon, ILocomotive, IStore, TStockInfoKey } from '../types';
|
||||||
|
import { LocoType, calculateSpeedLimit } from './speedLimitUtils';
|
||||||
|
|
||||||
// rodzaj: [tMaxPas, vMaxPas, tMaxTow, vMaxTow] | SM42: [tMax, vMax, ...]
|
// rodzaj: [tMaxPas, vMaxPas, tMaxTow, vMaxTow] | SM42: [tMax, vMax, ...]
|
||||||
const maxAllowedSpeedTable = {
|
// const maxAllowedSpeedTable = {
|
||||||
EU07: [
|
// EU07: [
|
||||||
[650, 125],
|
// [650, 125],
|
||||||
[2000, 70],
|
// [2000, 70],
|
||||||
],
|
// ],
|
||||||
EP07: [
|
// EP07: [
|
||||||
[650, 125],
|
// [650, 125],
|
||||||
[0, 0],
|
// [0, 0],
|
||||||
],
|
// ],
|
||||||
EP08: [
|
// EP08: [
|
||||||
[650, 140],
|
// [650, 140],
|
||||||
[0, 0],
|
// [0, 0],
|
||||||
],
|
// ],
|
||||||
ET41: [
|
// ET41: [
|
||||||
[700, 125],
|
// [700, 125],
|
||||||
[4000, 70],
|
// [4000, 70],
|
||||||
],
|
// ],
|
||||||
SM42: [
|
// SM42: [
|
||||||
[95, 90],
|
// [95, 90],
|
||||||
[200, 80],
|
// [200, 80],
|
||||||
[300, 70],
|
// [300, 70],
|
||||||
[450, 60],
|
// [450, 60],
|
||||||
[750, 50],
|
// [750, 50],
|
||||||
[1130, 40],
|
// [1130, 40],
|
||||||
[1720, 30],
|
// [1720, 30],
|
||||||
[2400, 20],
|
// [2400, 20],
|
||||||
],
|
// ],
|
||||||
};
|
// };
|
||||||
|
|
||||||
export function isLocomotive(vehicle: ILocomotive | ICarWagon): vehicle is ILocomotive {
|
export function isLocomotive(vehicle: ILocomotive | ICarWagon): vehicle is ILocomotive {
|
||||||
return (vehicle as ILocomotive).power !== undefined;
|
return (vehicle as ILocomotive).power !== undefined;
|
||||||
@@ -175,7 +176,23 @@ export function totalLength(state: IStore) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function maxStockSpeed(state: IStore) {
|
export function maxStockSpeed(state: IStore) {
|
||||||
return state.stockList.reduce((acc, stock) => (stock.maxSpeed < acc || acc == 0 ? stock.maxSpeed : acc), 0);
|
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 isTrainPassenger(state: IStore) {
|
export function isTrainPassenger(state: IStore) {
|
||||||
|
|||||||
Reference in New Issue
Block a user