Karta losowania składów (w.i.p.)

This commit is contained in:
2022-08-07 01:19:22 +02:00
parent 80d6140f43
commit 60d3f62a1c
5 changed files with 293 additions and 206 deletions
-7
View File
@@ -439,18 +439,11 @@ export default defineComponent({
} }
button { button {
font-size: 0.9em;
padding: 0.4em 0.55em;
margin-right: 0.5em; margin-right: 0.5em;
&:nth-child(5) { &:nth-child(5) {
margin-right: 0; margin-right: 0;
} }
&:focus-visible {
color: $accentColor;
border-color: $accentColor;
}
} }
} }
+206 -161
View File
@@ -20,7 +20,8 @@
<div class="select-box locos"> <div class="select-box locos">
<h3>LOKOMOTYWA</h3> <h3>LOKOMOTYWA</h3>
<select> <select v-model="chosenLocomotive">
<option :value="undefined">Wybierz lokomotywę</option>
<option v-for="loco in store.locoDataList.filter((l) => !l.type.includes('EN'))" :value="loco"> <option v-for="loco in store.locoDataList.filter((l) => !l.type.includes('EN'))" :value="loco">
{{ loco.type }} {{ loco.type }}
</option> </option>
@@ -30,30 +31,70 @@
<div class="select-box carwagons"> <div class="select-box carwagons">
<h3>WAGONY</h3> <h3>WAGONY</h3>
<ul class="carwagons-list"> <div class="rules">
<li v-for="stockWagon in chosenCarWagonList"> <button v-if="showRules" class="btn btn--outline" style="margin-bottom: 0.5em" @click="showRules = false">
<select class="select-type" v-model="stockWagon.wagon"> Ukryj zasady dodawania wagonów
<option :value="car" v-for="car in store.carDataList">{{ car.type }}</option> </button>
</select>
<select class="select-cargo"> <button v-else class="btn btn--outline" @click="showRules = true">Pokaż zasady dodawania wagonów</button>
<option value="empty" v-if="stockWagon.wagon.cargoList.length > 0">próżny</option>
<option value="empty" v-if="stockWagon.wagon.cargoList.length > 0">ładowny</option> <ul v-if="showRules" class="rules-list">
<option value="empty" v-if="stockWagon.wagon.cargoList.length > 0">losowo</option> <li>
<option value="test" v-for="cargo in stockWagon.wagon.cargoList">{{ cargo.id }}</option> nazwy wagonów w pierwszym polu muszą zaczynać się typem konstrukcyjnym (np. <i>111a</i> lub
<i>203V</i>), wariantem np. <i>111a Grafitti 1</i> lub jego początkiem, np. <i>111a PKPIC</i> (wtedy
losowanie obejmuje wszystkie dostępne wagony o takim początku)
</li>
<li>
ładunki w drugim polu można wybrać po uprzednim wpisaniu typu konstrukcyjnego wagonu towarowego
(zakładając, że je posiada)
</li>
<li>
liczba na trzecim polu - domyślnie 10 - to waga (szansa) wylosowania wagonu. Im większa waga, tym
większe prawdopodobieństwo
</li>
<li>liczba wariantów obejmująca losowanie danego wagonu pokazana jest na końcu rzędu</li>
</ul>
</div>
<ul class="carwagon-list">
<li v-for="(stockWagon, i) in chosenCarWagonList">
<input
class="carwagon-type g-input"
type="text"
list="types-datalist"
v-model="stockWagon.stockString"
@input="onCarWagonTypeInput(stockWagon)"
/>
<datalist id="types-datalist">
<option v-for="carOptionType in allCarOptionsList" :value="carOptionType">{{ carOptionType }}</option>
</datalist>
<select class="carwagon-cargo" v-model="stockWagon.chosenCargo">
<option :value="undefined">bez ładunku</option>
<option value="random" v-if="stockWagon.availableCargo && stockWagon.availableCargo.length > 0">
losowo
</option>
<option v-for="cargo in stockWagon.availableCargo" :value="cargo">
{{ cargo.id }}
</option>
</select> </select>
<span class="carwagon-chance"> <span class="carwagon-chance">
<input type="number" v-model="stockWagon.chance" max="100" min="1" /> <input type="number" v-model="stockWagon.chance" max="100" min="1" />
</span> </span>
<div>Warianty: {{ stockWagon.availableCars.length }}</div>
</li> </li>
</ul> </ul>
<button class="btn" @click="addCarWagon">+ DODAJ NOWY WAGON</button> <button class="btn btn--outline" @click="addCarWagon">+ DODAJ NOWY WAGON</button>
</div> </div>
</div> </div>
<button class="btn" style="font-size: 1.15em; margin-top: 2em" @click="() => {}">LOSUJ SKŁAD!</button> <button class="btn" style="font-size: 1.15em; margin-top: 2em" @click="generateRandomStock">LOSUJ SKŁAD!</button>
<button class="btn" style="font-size: 1.15em; margin-top: 2em" @click="store.isRandomizerCardOpen = false"> <button class="btn" style="font-size: 1.15em; margin-top: 2em" @click="store.isRandomizerCardOpen = false">
ZAMKNIJ ZAMKNIJ
</button> </button>
@@ -64,13 +105,18 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { ICarWagon, ILocomotive, ICargo, IStock } from '../types'; import { ICargo, ICarWagon, ILocomotive, IStock, IVehicleData } from '../types';
import { useStore } from '../store'; import { useStore } from '../store';
import stockMixin from '../mixins/stockMixin';
interface RandomStockCarWagon { interface RandomStockCarWagon {
wagon: ICarWagon; stockString: string;
chance: number; chance: number;
availableCars: ICarWagon[];
availableCargo?: ICargo[];
chosenCargo?: ICargo;
} }
export default defineComponent({ export default defineComponent({
@@ -82,6 +128,8 @@ export default defineComponent({
}; };
}, },
mixins: [stockMixin],
activated() { activated() {
(this.$refs['cardWrapper'] as any).focus(); (this.$refs['cardWrapper'] as any).focus();
}, },
@@ -93,66 +141,128 @@ export default defineComponent({
chosenCarWagonList: [] as RandomStockCarWagon[], chosenCarWagonList: [] as RandomStockCarWagon[],
chosenLocomotive: undefined as ILocomotive | undefined, chosenLocomotive: undefined as ILocomotive | undefined,
// chosenCarTypes: [] as string[], showRules: false,
// cargoFillModeList: [
// {
// id: 'cargo-random',
// value: 'LOSOWO',
// },
// {
// id: 'cargo-filled',
// value: 'ŁADOWNE',
// },
// {
// id: 'cargo-empty',
// value: 'PRÓŻNE',
// },
// ] as { id: CargoFillModeType; value: string }[],
// chosenCargoFillMode: 'cargo-random' as CargoFillModeType,
// icons: {
// randomize: randomizeIcon,
// },
// focusedCar: null as ICarWagon | null,
// isPreviewLoading: false, // isPreviewLoading: false,
// cargoTypes: [
// '203V',
// '208Kf',
// '209c',
// '29R',
// '304C',
// '304Ca',
// '401Ka',
// '401Zb',
// '408S',
// '412W',
// '412Z',
// '424Z',
// '426S',
// '429W',
// '441V',
// '504a',
// '612a',
// '627Z',
// ],
// carUsage: carUsage as { [key: string]: string },
}), }),
computed: {
allCarOptionsList() {
const list: string[] = [];
this.store.carDataList.forEach((carData) => {
const splittedTypeList = carData.type.split('_');
for (let i = 0; i < splittedTypeList.length; i++) {
const typeToCheck = carData.type
.split('_', i + 1)
.join('_')
.replace(/_/g, ' ');
if (!list.includes(typeToCheck)) list.push(typeToCheck);
}
});
return list.sort((a, b) => a > b ? 1 : -1);
},
},
methods: { methods: {
onCarWagonTypeInput(carWagon: RandomStockCarWagon) {
const constructionType = carWagon.stockString.split(' ')[0];
const carWagonObj = this.store.carDataList.find((car) => car.constructionType == constructionType);
const allAvailableCars = this.store.carDataList.filter((car) =>
car.type.startsWith(carWagon.stockString.replace(/ /g, '_'))
);
carWagon.availableCars = allAvailableCars;
carWagon.availableCargo = carWagonObj?.cargoList || undefined;
if (!carWagonObj?.cargoList) {
carWagon.chosenCargo = undefined;
}
},
addCarWagon() { addCarWagon() {
const randomStockCarWagon: RandomStockCarWagon = { const randomStockCarWagon: RandomStockCarWagon = {
chance: 100, stockString: '111a PKPIC',
wagon: this.store.carDataList[0], chance: 10,
chosenCargo: undefined,
availableCargo: undefined,
availableCars: this.store.carDataList.filter((car) => car.type.startsWith('111a_PKPIC')),
}; };
this.chosenCarWagonList.push(randomStockCarWagon); this.chosenCarWagonList.push(randomStockCarWagon);
}, },
generateRandomStock() {
let totalLength = 0;
let totalMass = 0;
let generatedStockList: IStock[] = [];
// if (!this.chosenLocomotive) return;
if (this.chosenCarWagonList.length == 0) return;
// generatedStockList.push(this.getStockObject(this.chosenLocomotive));
// totalLength += this.chosenLocomotive.length;
// totalMass += this.chosenLocomotive.mass;
while (generatedStockList.length < 25) {
const randCarWagon = this.getRandomCarWagon();
generatedStockList.push(this.getStockObject(randCarWagon));
totalLength += randCarWagon.length;
totalMass += randCarWagon.mass;
}
console.log(generatedStockList);
},
getRandomCarWagon(): ICarWagon {
const totalChancePot = this.chosenCarWagonList.reduce((total, car) => {
total += car.chance;
return total;
}, 0);
let rand = Math.random() * totalChancePot;
let randCarWagon: ICarWagon | undefined = undefined;
for (let wagonItem of this.chosenCarWagonList) {
if (rand < wagonItem.chance) {
randCarWagon = { ...wagonItem.availableCars[Math.floor(Math.random() * wagonItem.availableCars.length)] };
break;
}
rand -= wagonItem.chance;
}
return randCarWagon!;
},
// getRandomStockItem() {
// const totalChancePot = this.chosenCarWagonList.reduce((total, car) => {
// total += car.chance;
// return total;
// }, 0);
// let rand = Math.random() * totalChancePot;
// let randomCarWagon: RandomStockCarWagon | undefined = undefined;
// for (let wagonItem of this.chosenCarWagonList) {
// if (rand < wagonItem.chance) {
// randomCarWagon = { ...wagonItem };
// break;
// }
// rand -= wagonItem.chance;
// }
// return randomCarWagon!;
// },
// randomize() { // randomize() {
// if (this.chosenCarTypes.length == 0) { // if (this.chosenCarTypes.length == 0) {
// alert('Wybierz przynajmniej jeden rodzaj wagonów!'); // alert('Wybierz przynajmniej jeden rodzaj wagonów!');
@@ -234,60 +344,6 @@ export default defineComponent({
// this.store.isRandomizerCardOpen = false; // this.store.isRandomizerCardOpen = false;
// }, // },
// addLocomotive() {
// const previousStock =
// this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
// if (previousStock && previousStock.type == loco.type) {
// this.store.stockList[this.store.stockList.length - 1].count++;
// return;
// }
// const stockObj: IStock = {
// id: `${Date.now() + this.store.stockList.length}`,
// type: loco.type,
// length: loco.length,
// mass: loco.mass,
// maxSpeed: loco.maxSpeed,
// isLoco: true,
// cargo: undefined,
// count: 1,
// imgSrc: loco.imageSrc,
// useType: loco.power,
// supportersOnly: loco.supportersOnly,
// };
// if (this.store.stockList.length > 0 && !this.store.stockList[0].isLoco) this.store.stockList.unshift(stockObj);
// else this.store.stockList.push(stockObj);
// },
addCar(car: ICarWagon, cargo?: ICargo) {
const previousStock =
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) {
this.store.stockList[this.store.stockList.length - 1].count++;
return;
}
const stockObj: IStock = {
id: `${Date.now() + this.store.stockList.length}`,
type: car.type,
length: car.length,
mass: car.mass,
maxSpeed: car.maxSpeed,
isLoco: false,
cargo: car.loadable && cargo ? cargo : undefined,
count: 1,
imgSrc: car.imageSrc,
useType: car.useType,
supportersOnly: car.supportersOnly,
};
this.store.stockList.push(stockObj);
},
}, },
}); });
</script> </script>
@@ -314,7 +370,7 @@ export default defineComponent({
height: 90vh; height: 90vh;
max-height: 900px; max-height: 900px;
background: #242424; background: #111;
@media screen and (max-width: 700px) { @media screen and (max-width: 700px) {
width: 95%; width: 95%;
@@ -323,10 +379,6 @@ export default defineComponent({
border-radius: 1em; border-radius: 1em;
} }
p {
font-size: 1.2em;
}
h1 { h1 {
text-align: center; text-align: center;
color: $accentColor; color: $accentColor;
@@ -337,14 +389,13 @@ h3 {
margin: 0 0 0.5em 0; margin: 0 0 0.5em 0;
} }
.car-choice div { .rules {
display: grid; margin: 0.5em 0;
grid-template-columns: repeat(6, 1fr); ul {
justify-content: center; list-style: inside;
border: 1px solid $accentColor;
@media screen and (max-width: 800px) { padding: 0.5em;
grid-template-columns: repeat(4, 1fr);
} }
} }
@@ -398,6 +449,31 @@ h3 {
} }
} }
.carwagon-list li {
margin: 0.5em 0;
display: flex;
align-items: center;
> * {
margin-right: 0.5em;
}
input.carwagon-type {
width: auto;
}
select.carwagon-cargo {
max-width: 150px;
}
.carwagon-chance {
input {
font-weight: bold;
width: auto;
}
}
}
.random-stock-selections { .random-stock-selections {
text-align: left; text-align: left;
@@ -406,37 +482,6 @@ h3 {
} }
} }
ul.carwagons-list li select {
margin: 0.5em 0.5em 0 0;
&.select-type {
width: 250px;
}
&.select-cargo {
width: 120px;
}
}
.carwagon-chance {
position: relative;
font-size: 1.2em;
font-weight: bold;
input {
background-color: white;
height: 1.6em;
border: none;
width: 3em;
}
&::after {
content: '%';
top: 0;
right: -1em;
position: absolute;
}
}
@media screen and (max-width: 600px) { @media screen and (max-width: 600px) {
.car-preview .image-wrapper { .car-preview .image-wrapper {
width: 20em; width: 20em;
+5 -5
View File
@@ -1342,7 +1342,7 @@
], ],
[ [
"304C_PLK_Rob", "304C_PLK_Rob",
"304c", "304C",
false, false,
false, false,
"140", "140",
@@ -1446,7 +1446,7 @@
], ],
[ [
"Gor77_PKP_Bhp_01", "Gor77_PKP_Bhp_01",
"Bhp", "Gor77",
false, false,
false, false,
"120", "120",
@@ -1454,7 +1454,7 @@
], ],
[ [
"Gor77_PKP_Bhp_02", "Gor77_PKP_Bhp_02",
"Bhp", "Gor77",
false, false,
false, false,
"120", "120",
@@ -1462,7 +1462,7 @@
], ],
[ [
"Gor77_PKP_Bhp_03", "Gor77_PKP_Bhp_03",
"Bhp", "Gor77",
false, false,
false, false,
"120", "120",
@@ -1585,7 +1585,7 @@
], ],
[ [
"29R_PLPOL_Zaekk_01", "29R_PLPOL_Zaekk_01",
"29R_PLPOL", "29R",
true, true,
false, false,
"100", "100",
+65
View File
@@ -0,0 +1,65 @@
import { defineComponent } from 'vue';
import { useStore } from '../store';
import { ICargo, ICarWagon, ILocomotive, IStock, Vehicle } from '../types';
import { isLocomotive } from '../utils/vehicleUtils';
export default defineComponent({
setup() {
return {
store: useStore(),
};
},
methods: {
getStockId() {
return `${Math.random().toString(36).slice(5)}`;
},
getStockObject(vehicle: Vehicle, cargo?: ICargo, count = 1): IStock {
const isLoco = isLocomotive(vehicle);
return {
id: this.getStockId(),
type: vehicle.type,
length: vehicle.length,
mass: vehicle.mass,
maxSpeed: vehicle.maxSpeed,
isLoco,
cargo: !isLoco && vehicle.loadable && cargo ? cargo : undefined,
count,
imgSrc: vehicle.imageSrc,
useType: isLoco ? vehicle.power : vehicle.useType,
supportersOnly: false,
};
},
addLocomotive(loco: ILocomotive) {
const previousStock =
this.store.stockList.length > 0 ? this.store.stockList[this.store.stockList.length - 1] : null;
if (previousStock && previousStock.type == loco.type) {
this.store.stockList[this.store.stockList.length - 1].count++;
return;
}
const stockObj = this.getStockObject(loco);
if (this.store.stockList.length > 0 && !this.store.stockList[0].isLoco) this.store.stockList.unshift(stockObj);
else this.store.stockList.push(stockObj);
},
addCarWagon(car: ICarWagon, cargo?: ICargo) {
const previousStock =
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) {
this.store.stockList[this.store.stockList.length - 1].count++;
return;
}
const stockObj = this.getStockObject(car, cargo);
this.store.stockList.push(stockObj);
},
},
});
+17 -33
View File
@@ -54,12 +54,6 @@ a {
} }
} }
p {
font-size: 1.2em;
font-weight: bold;
color: $accentColor;
}
select, select,
option, option,
input, input,
@@ -87,17 +81,22 @@ button {
} }
button.btn { button.btn {
padding: 0.25em 1em; padding: 0.4em 0.75em;
border-radius: 0.25em;
border: 2px solid white;
outline: none; outline: none;
background: none; background-color: #222;
transition: all 250ms; transition: all 250ms;
&.btn--outline {
background: none;
font-weight: bold;
outline: 1px solid $accentColor;
}
&:focus-visible { &:focus-visible {
color: $accentColor; color: $accentColor;
outline: 1px solid white;
} }
&[data-disabled='true'] { &[data-disabled='true'] {
@@ -112,7 +111,7 @@ button.btn {
&--text { &--text {
font-weight: bold; font-weight: bold;
transition: all 250ms; transition: all 250ms;
border: none; background: none;
&:focus-visible { &:focus-visible {
outline: 1px solid white; outline: 1px solid white;
@@ -121,6 +120,7 @@ button.btn {
&--choice { &--choice {
padding: 0.25em 0.3em; padding: 0.25em 0.3em;
background-color: #222;
&:focus-visible { &:focus-visible {
outline: 1px solid white; outline: 1px solid white;
@@ -128,28 +128,8 @@ button.btn {
} }
} }
button.btn-rect { select,
width: 1.5em; input {
height: 1.5em;
font-size: 1.65em;
line-height: 1em;
border-radius: 0.25em;
border: 2px solid black;
outline: none;
background: white;
color: black;
transition: all 250ms;
&:hover {
color: white;
background-color: black;
}
}
select {
background: none; background: none;
border: 2px solid white; border: 2px solid white;
outline: none; outline: none;
@@ -160,6 +140,10 @@ select {
font-size: 1em; font-size: 1em;
width: 18em; width: 18em;
&:focus-visible {
border-color: $accentColor;
}
} }
option { option {