mirror of
https://github.com/morbalint/kemkas.git
synced 2026-07-18 03:13:46 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c5fa7a92d9 | |||
| 700684ecfd | |||
| 43959ae94f | |||
| 88b0379c93 |
@@ -8,21 +8,23 @@ import {AppDispatch, RootState} from "../../store";
|
|||||||
import {characterSelector, setHarcosSpecialization} from "../domain-models/characterSlice";
|
import {characterSelector, setHarcosSpecialization} from "../domain-models/characterSlice";
|
||||||
|
|
||||||
function HarcosFegyverSpecializacio(props: {
|
function HarcosFegyverSpecializacio(props: {
|
||||||
szint: number
|
harcosSzint: number,
|
||||||
|
karakterSzint: number,
|
||||||
}) {
|
}) {
|
||||||
const {
|
const {
|
||||||
szint
|
harcosSzint,
|
||||||
|
karakterSzint,
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
const dispatch = useDispatch.withTypes<AppDispatch>()()
|
const dispatch = useDispatch.withTypes<AppDispatch>()()
|
||||||
const character = useSelector.withTypes<RootState>()(characterSelector)
|
const character = useSelector.withTypes<RootState>()(characterSelector)
|
||||||
const specialization = character.szintlepesek[szint-1].harcosFegyver || 'kard_hosszu'
|
const specialization = character.szintlepesek[karakterSzint-1]?.harcosFegyver || 'kard_hosszu'
|
||||||
const existingSpecializations = character.szintlepesek.filter(x => x.harcosFegyver != null).map(x => x.harcosFegyver! as string)
|
const existingSpecializations = character.szintlepesek.filter(x => x.harcosFegyver != null).map(x => x.harcosFegyver! as string)
|
||||||
const changeSpecialization = (specialization: string) => dispatch(setHarcosSpecialization({szint, fegyver: specialization}))
|
const changeSpecialization = (specialization: string) => dispatch(setHarcosSpecialization({szint: karakterSzint, fegyver: specialization}))
|
||||||
|
|
||||||
const fegyver = GetFegyver(specialization)
|
const fegyver = GetFegyver(specialization)
|
||||||
const availableFegyverek = AllowedFegyver(Osztaly2E.Harcos)
|
const availableFegyverek = AllowedFegyver(Osztaly2E.Harcos)
|
||||||
const pickableFegyverek = availableFegyverek.filter(f => f.Id === specialization || existingSpecializations.filter(x => x === f.Id).length < (szint < 9 ? 1 : 2))
|
const pickableFegyverek = availableFegyverek.filter(f => f.Id === specialization || existingSpecializations.filter(x => x === f.Id).length < (harcosSzint < 9 ? 1 : 2))
|
||||||
|
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
@@ -32,7 +34,7 @@ function HarcosFegyverSpecializacio(props: {
|
|||||||
fegyverek={pickableFegyverek}
|
fegyverek={pickableFegyverek}
|
||||||
selectedId={specialization}
|
selectedId={specialization}
|
||||||
onChange={changeSpecialization}
|
onChange={changeSpecialization}
|
||||||
dataTestId={"harcos-specialization-" + szint}
|
dataTestId={"harcos-specialization-" + karakterSzint}
|
||||||
/>
|
/>
|
||||||
{fegyver == null && <span className='form-field-error'>Ismeretlen fegyver: {specialization}</span>}
|
{fegyver == null && <span className='form-field-error'>Ismeretlen fegyver: {specialization}</span>}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,248 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {fireEvent, render} from "@testing-library/react";
|
||||||
|
import {configureStore} from "@reduxjs/toolkit";
|
||||||
|
import {Provider} from "react-redux";
|
||||||
|
import LevelUps from "./LevelUps";
|
||||||
|
import userReducer from "../../shared/domain-models/userSlice";
|
||||||
|
import characterReducer, {setCharacter} from "../domain-models/characterSlice";
|
||||||
|
import {AllowedFegyver} from "../domain-models/allowed-fegyver";
|
||||||
|
import {Osztaly2E} from "../domain-models/osztaly2E";
|
||||||
|
import {ChangeOsztalyAtSzint, DefaultKarakter, Karakter2E} from "../domain-models/karakter2E";
|
||||||
|
import {LevelUp} from "../domain-models/szintlepes";
|
||||||
|
import {GetAvailableKepzettsegek} from "../domain-models/kepzettsegek2E";
|
||||||
|
|
||||||
|
function applyLevelUp(karakter: Karakter2E): Karakter2E {
|
||||||
|
let next: Karakter2E | undefined;
|
||||||
|
LevelUp(karakter, updated => {
|
||||||
|
next = updated;
|
||||||
|
});
|
||||||
|
expect(next).toBeDefined();
|
||||||
|
return next as Karakter2E;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("LevelUps Harcos specialization indexing", () => {
|
||||||
|
it("updates specialization on the selected character level for multiclass", async () => {
|
||||||
|
const level1Tolvaj: Karakter2E = {
|
||||||
|
...DefaultKarakter,
|
||||||
|
szint: 1,
|
||||||
|
szintlepesek: [{
|
||||||
|
osztaly: Osztaly2E.Tolvaj,
|
||||||
|
HProll: 6,
|
||||||
|
}],
|
||||||
|
tolvajKepzettsegek: [],
|
||||||
|
varazslatok: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const level2Auto = applyLevelUp(level1Tolvaj);
|
||||||
|
const karakter = ChangeOsztalyAtSzint(level2Auto, Osztaly2E.Harcos, 2);
|
||||||
|
|
||||||
|
const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
user: userReducer,
|
||||||
|
character2E: characterReducer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
store.dispatch(setCharacter(karakter));
|
||||||
|
|
||||||
|
const sut = render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<LevelUps
|
||||||
|
karakter={store.getState().character2E}
|
||||||
|
changeKarakter={(updated) => store.dispatch(setCharacter(updated))}
|
||||||
|
/>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
const selector = await sut.findByTestId("harcos-specialization-2");
|
||||||
|
|
||||||
|
const currentSpec = karakter.szintlepesek[1]?.harcosFegyver;
|
||||||
|
const nextSpec = AllowedFegyver(Osztaly2E.Harcos)
|
||||||
|
.map(x => x.Id)
|
||||||
|
.find(id => id !== currentSpec);
|
||||||
|
|
||||||
|
expect(nextSpec).toBeDefined();
|
||||||
|
fireEvent.change(selector, {target: {value: nextSpec as string}});
|
||||||
|
|
||||||
|
const stateAfter = store.getState().character2E;
|
||||||
|
expect(stateAfter.szintlepesek[0]?.harcosFegyver).toBeUndefined();
|
||||||
|
expect(stateAfter.szintlepesek[1]?.harcosFegyver).toBe(nextSpec);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not render tulajdonsag selector at level 4 when all abilities are maxed", () => {
|
||||||
|
const maxedCharacter: Karakter2E = {
|
||||||
|
...DefaultKarakter,
|
||||||
|
szint: 1,
|
||||||
|
tulajdonsagok: {
|
||||||
|
t_ero: 18,
|
||||||
|
t_ugy: 18,
|
||||||
|
t_egs: 18,
|
||||||
|
t_int: 18,
|
||||||
|
t_bol: 18,
|
||||||
|
t_kar: 18,
|
||||||
|
},
|
||||||
|
szintlepesek: [{
|
||||||
|
osztaly: Osztaly2E.Pap,
|
||||||
|
HProll: 8,
|
||||||
|
}],
|
||||||
|
tolvajKepzettsegek: [],
|
||||||
|
varazslatok: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const level2 = applyLevelUp(maxedCharacter);
|
||||||
|
const level3 = applyLevelUp(level2);
|
||||||
|
const level4 = applyLevelUp(level3);
|
||||||
|
|
||||||
|
expect(level4.szintlepesek[3]?.tulajdonsagNoveles).toBeUndefined();
|
||||||
|
|
||||||
|
const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
user: userReducer,
|
||||||
|
character2E: characterReducer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
store.dispatch(setCharacter(level4));
|
||||||
|
|
||||||
|
const sut = render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<LevelUps
|
||||||
|
karakter={store.getState().character2E}
|
||||||
|
changeKarakter={(updated) => store.dispatch(setCharacter(updated))}
|
||||||
|
/>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(sut.queryByTestId("tulajdonsag-4")).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not render kaloz krit selector when tengeresz milestone exists but krit is missing", () => {
|
||||||
|
const inconsistentTengeresz: Karakter2E = {
|
||||||
|
...DefaultKarakter,
|
||||||
|
szint: 3,
|
||||||
|
szintlepesek: [
|
||||||
|
{
|
||||||
|
osztaly: Osztaly2E.Tengeresz,
|
||||||
|
HProll: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
osztaly: Osztaly2E.Tengeresz,
|
||||||
|
HProll: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
osztaly: Osztaly2E.Tengeresz,
|
||||||
|
HProll: 7,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tolvajKepzettsegek: [],
|
||||||
|
varazslatok: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
user: userReducer,
|
||||||
|
character2E: characterReducer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
store.dispatch(setCharacter(inconsistentTengeresz));
|
||||||
|
|
||||||
|
const sut = render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<LevelUps
|
||||||
|
karakter={store.getState().character2E}
|
||||||
|
changeKarakter={(updated) => store.dispatch(setCharacter(updated))}
|
||||||
|
/>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(sut.queryByTestId("kaloz-krit-3")).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows and updates Tolvaj extra skill on multiclass Tolvaj level 5", async () => {
|
||||||
|
const multiclassTolvaj: Karakter2E = {
|
||||||
|
...DefaultKarakter,
|
||||||
|
szint: 6,
|
||||||
|
szintlepesek: [
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6 },
|
||||||
|
{ osztaly: Osztaly2E.Harcos, HProll: 10 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 4 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 5 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 3, tolvajExtraKepzettseg: "k_meregkeveres" },
|
||||||
|
],
|
||||||
|
tolvajKepzettsegek: ["k_alcazas", "k_csapdak", "k_egyensulyozas", "k_hamisitas"],
|
||||||
|
varazslatok: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
user: userReducer,
|
||||||
|
character2E: characterReducer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
store.dispatch(setCharacter(multiclassTolvaj));
|
||||||
|
|
||||||
|
const sut = render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<LevelUps
|
||||||
|
karakter={store.getState().character2E}
|
||||||
|
changeKarakter={(updated) => store.dispatch(setCharacter(updated))}
|
||||||
|
/>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
const selector = await sut.findByTestId("tolvaj-extra-kepzettseg-6");
|
||||||
|
const nextKepzettseg = GetAvailableKepzettsegek(multiclassTolvaj)
|
||||||
|
.map(x => x.Id)
|
||||||
|
.find(id => id !== multiclassTolvaj.szintlepesek[5]?.tolvajExtraKepzettseg);
|
||||||
|
|
||||||
|
expect(nextKepzettseg).toBeDefined();
|
||||||
|
fireEvent.change(selector, {target: {value: nextKepzettseg as string}});
|
||||||
|
|
||||||
|
const stateAfter = store.getState().character2E;
|
||||||
|
expect(stateAfter.szintlepesek[5]?.tolvajExtraKepzettseg).toBe(nextKepzettseg);
|
||||||
|
expect(stateAfter.szintlepesek[4]?.tolvajExtraKepzettseg).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("at Tolvaj level 9 selector includes class-restricted non-Tolvaj skills", async () => {
|
||||||
|
const tolvajLevel9: Karakter2E = {
|
||||||
|
...DefaultKarakter,
|
||||||
|
szint: 9,
|
||||||
|
szintlepesek: [
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 5 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 4 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 3 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 2, tolvajExtraKepzettseg: "k_meregkeveres" },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 4 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 5 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 3 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6, tolvajExtraKepzettseg: "k_alkimia" },
|
||||||
|
],
|
||||||
|
tolvajKepzettsegek: ["k_alcazas", "k_csapdak", "k_egyensulyozas", "k_hamisitas"],
|
||||||
|
varazslatok: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
user: userReducer,
|
||||||
|
character2E: characterReducer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
store.dispatch(setCharacter(tolvajLevel9));
|
||||||
|
|
||||||
|
const sut = render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<LevelUps
|
||||||
|
karakter={store.getState().character2E}
|
||||||
|
changeKarakter={(updated) => store.dispatch(setCharacter(updated))}
|
||||||
|
/>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
const selector = await sut.findByTestId("tolvaj-extra-kepzettseg-9");
|
||||||
|
const arcaneOption = selector.querySelector('option[value="k_csillagjoslas"]');
|
||||||
|
expect(arcaneOption).not.toBeNull();
|
||||||
|
|
||||||
|
fireEvent.change(selector, {target: {value: "k_csillagjoslas"}});
|
||||||
|
expect(store.getState().character2E.szintlepesek[8]?.tolvajExtraKepzettseg).toBe("k_csillagjoslas");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -41,6 +41,8 @@ function LevelUp(props: {
|
|||||||
const kalozSzint = classLevels[Osztaly2E.Tengeresz]
|
const kalozSzint = classLevels[Osztaly2E.Tengeresz]
|
||||||
const tolvajSzint = classLevels[Osztaly2E.Tolvaj]
|
const tolvajSzint = classLevels[Osztaly2E.Tolvaj]
|
||||||
const szintlepes = karakter.szintlepesek[szint-1];
|
const szintlepes = karakter.szintlepesek[szint-1];
|
||||||
|
const tulajdonsagNoveles = szintlepes?.tulajdonsagNoveles;
|
||||||
|
const kalozKritikus = szintlepes?.kalozKritikus;
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
<div className='row mt-3'>
|
<div className='row mt-3'>
|
||||||
@@ -54,10 +56,10 @@ function LevelUp(props: {
|
|||||||
osztalySzint={classLevels[osztaly]}
|
osztalySzint={classLevels[osztaly]}
|
||||||
dataTestId={`osztaly-${szint}`}
|
dataTestId={`osztaly-${szint}`}
|
||||||
/>}
|
/>}
|
||||||
{szint % 4 === 0 &&
|
{szint % 4 === 0 && tulajdonsagNoveles != null &&
|
||||||
<TulajdonsagNoveles
|
<TulajdonsagNoveles
|
||||||
tulajdonsagok={karakter.tulajdonsagok}
|
tulajdonsagok={karakter.tulajdonsagok}
|
||||||
tulajdonsagNoveles={karakter.szintlepesek[szint-1].tulajdonsagNoveles!}
|
tulajdonsagNoveles={tulajdonsagNoveles}
|
||||||
changeTulajdonsagNoveles={changeTulajdonsagNoveles}
|
changeTulajdonsagNoveles={changeTulajdonsagNoveles}
|
||||||
dataTestId={`tulajdonsag-${szint}`}
|
dataTestId={`tulajdonsag-${szint}`}
|
||||||
/>}
|
/>}
|
||||||
@@ -69,12 +71,13 @@ function LevelUp(props: {
|
|||||||
/>
|
/>
|
||||||
{osztaly === Osztaly2E.Harcos && harcosSzint % 2 === 1 &&
|
{osztaly === Osztaly2E.Harcos && harcosSzint % 2 === 1 &&
|
||||||
<HarcosFegyverSpecializacio
|
<HarcosFegyverSpecializacio
|
||||||
szint={harcosSzint}
|
harcosSzint={harcosSzint}
|
||||||
|
karakterSzint={szint}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{osztaly === Osztaly2E.Tengeresz && kalozSzint % 3 === 0 &&
|
{osztaly === Osztaly2E.Tengeresz && kalozSzint % 3 === 0 && kalozKritikus != null &&
|
||||||
<KalozKritikus
|
<KalozKritikus
|
||||||
kritFegyverId={szintlepes.kalozKritikus!}
|
kritFegyverId={kalozKritikus}
|
||||||
existingKrits={karakter.szintlepesek.map(x => x.kalozKritikus)}
|
existingKrits={karakter.szintlepesek.map(x => x.kalozKritikus)}
|
||||||
changeKrit={changeKalozKritikus}
|
changeKrit={changeKalozKritikus}
|
||||||
szint={kalozSzint}
|
szint={kalozSzint}
|
||||||
@@ -82,12 +85,17 @@ function LevelUp(props: {
|
|||||||
}
|
}
|
||||||
{osztaly === Osztaly2E.Tolvaj
|
{osztaly === Osztaly2E.Tolvaj
|
||||||
&& (tolvajSzint === 5 || tolvajSzint === 9)
|
&& (tolvajSzint === 5 || tolvajSzint === 9)
|
||||||
&& szintlepes.tolvajExtraKepzettseg != null &&
|
&& szintlepes?.tolvajExtraKepzettseg != null &&
|
||||||
<div className='row m-2'>
|
<div className='row m-2'>
|
||||||
<label className='col-md-2 col-sm-3 col-form-label'>Extra képzettség</label>
|
<label className='col-md-2 col-sm-3 col-form-label'>Extra képzettség</label>
|
||||||
<KepzettsegSelector
|
<KepzettsegSelector
|
||||||
selected={Kepzettsegek[szintlepes.tolvajExtraKepzettseg]}
|
selected={Kepzettsegek[szintlepes!.tolvajExtraKepzettseg]}
|
||||||
kepzettsegek={[Kepzettsegek[szintlepes.tolvajExtraKepzettseg], ...GetAvailableKepzettsegek(karakter)]}
|
kepzettsegek={[
|
||||||
|
Kepzettsegek[szintlepes!.tolvajExtraKepzettseg],
|
||||||
|
...GetAvailableKepzettsegek(karakter, {
|
||||||
|
ignoreClassRestrictions: tolvajSzint === 9,
|
||||||
|
})
|
||||||
|
]}
|
||||||
dataTestId={`tolvaj-extra-kepzettseg-${szint}`}
|
dataTestId={`tolvaj-extra-kepzettseg-${szint}`}
|
||||||
changeKepzettseg={changeExtraTolvajKepzettseg}
|
changeKepzettseg={changeExtraTolvajKepzettseg}
|
||||||
/>
|
/>
|
||||||
@@ -100,16 +108,19 @@ export function LevelUps(props: {karakter: Karakter2E, changeKarakter: (inputs:
|
|||||||
const {karakter, changeKarakter} = props;
|
const {karakter, changeKarakter} = props;
|
||||||
|
|
||||||
const tulajdonsagokAtSzint = (szint: number) => TulajdonsagokTotal({...karakter, szintlepesek: karakter.szintlepesek.slice(0, szint)})
|
const tulajdonsagokAtSzint = (szint: number) => TulajdonsagokTotal({...karakter, szintlepesek: karakter.szintlepesek.slice(0, szint)})
|
||||||
|
const szintlepesAt = (szint: number) => karakter.szintlepesek[szint-1]!
|
||||||
|
|
||||||
const changeRolledHPAtSzint = (szint: number) => (newHProll: number) => {
|
const changeRolledHPAtSzint = (szint: number) => (newHProll: number) => {
|
||||||
changeKarakter({...karakter, szintlepesek: arraySetN(karakter.szintlepesek, szint-1, {...karakter.szintlepesek[szint-1], HProll: newHProll})})
|
const szintlepes = szintlepesAt(szint)
|
||||||
|
changeKarakter({...karakter, szintlepesek: arraySetN(karakter.szintlepesek, szint-1, {...szintlepes, HProll: newHProll})})
|
||||||
console.log(karakter)
|
console.log(karakter)
|
||||||
}
|
}
|
||||||
const changeTulajdonsagNovelesAtSzint = (szint: number) => {
|
const changeTulajdonsagNovelesAtSzint = (szint: number) => {
|
||||||
return (t: Tulajdonsag2E) => {
|
return (t: Tulajdonsag2E) => {
|
||||||
|
const szintlepes = szintlepesAt(szint)
|
||||||
changeKarakter({...karakter,
|
changeKarakter({...karakter,
|
||||||
szintlepesek: arraySetN(karakter.szintlepesek, szint-1, {
|
szintlepesek: arraySetN(karakter.szintlepesek, szint-1, {
|
||||||
...karakter.szintlepesek[szint-1],
|
...szintlepes,
|
||||||
tulajdonsagNoveles: t
|
tulajdonsagNoveles: t
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -118,10 +129,11 @@ export function LevelUps(props: {karakter: Karakter2E, changeKarakter: (inputs:
|
|||||||
|
|
||||||
const changeKalozKritikusAtSzint = (szint: number) => {
|
const changeKalozKritikusAtSzint = (szint: number) => {
|
||||||
return (krit: string) => {
|
return (krit: string) => {
|
||||||
|
const szintlepes = szintlepesAt(szint)
|
||||||
changeKarakter({
|
changeKarakter({
|
||||||
...karakter,
|
...karakter,
|
||||||
szintlepesek: arraySetN(karakter.szintlepesek, szint-1, {
|
szintlepesek: arraySetN(karakter.szintlepesek, szint-1, {
|
||||||
...karakter.szintlepesek[szint-1],
|
...szintlepes,
|
||||||
kalozKritikus: krit
|
kalozKritikus: krit
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -130,10 +142,11 @@ export function LevelUps(props: {karakter: Karakter2E, changeKarakter: (inputs:
|
|||||||
|
|
||||||
const changeExtraTolvajKepzettseg = (szint: number) => {
|
const changeExtraTolvajKepzettseg = (szint: number) => {
|
||||||
return (k: KepzettsegId) => {
|
return (k: KepzettsegId) => {
|
||||||
|
const szintlepes = szintlepesAt(szint)
|
||||||
changeKarakter({
|
changeKarakter({
|
||||||
...karakter,
|
...karakter,
|
||||||
szintlepesek: arraySetN(karakter.szintlepesek, szint-1, {
|
szintlepesek: arraySetN(karakter.szintlepesek, szint-1, {
|
||||||
...karakter.szintlepesek[szint-1],
|
...szintlepes,
|
||||||
tolvajExtraKepzettseg: k,
|
tolvajExtraKepzettseg: k,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -144,10 +157,13 @@ export function LevelUps(props: {karakter: Karakter2E, changeKarakter: (inputs:
|
|||||||
|
|
||||||
return <>
|
return <>
|
||||||
{levels.slice(1).map(szint =>
|
{levels.slice(1).map(szint =>
|
||||||
|
{
|
||||||
|
const szintlepes = szintlepesAt(szint)
|
||||||
|
return (
|
||||||
<LevelUp
|
<LevelUp
|
||||||
key={`level-up-${szint}`}
|
key={`level-up-${szint}`}
|
||||||
szint={szint}
|
szint={szint}
|
||||||
osztaly={karakter.szintlepesek[szint-1].osztaly}
|
osztaly={szintlepes.osztaly}
|
||||||
karakter={{...karakter, szintlepesek: karakter.szintlepesek.slice(0, szint) ,tulajdonsagok: tulajdonsagokAtSzint(szint)}}
|
karakter={{...karakter, szintlepesek: karakter.szintlepesek.slice(0, szint) ,tulajdonsagok: tulajdonsagokAtSzint(szint)}}
|
||||||
changeTulajdonsagNoveles={changeTulajdonsagNovelesAtSzint(szint)}
|
changeTulajdonsagNoveles={changeTulajdonsagNovelesAtSzint(szint)}
|
||||||
changeRolledHP={changeRolledHPAtSzint(szint)}
|
changeRolledHP={changeRolledHPAtSzint(szint)}
|
||||||
@@ -155,6 +171,8 @@ export function LevelUps(props: {karakter: Karakter2E, changeKarakter: (inputs:
|
|||||||
changeOsztaly={(o) => changeKarakter(ChangeOsztalyAtSzint(karakter, o, szint))}
|
changeOsztaly={(o) => changeKarakter(ChangeOsztalyAtSzint(karakter, o, szint))}
|
||||||
changeExtraTolvajKepzettseg={changeExtraTolvajKepzettseg(szint)}
|
changeExtraTolvajKepzettseg={changeExtraTolvajKepzettseg(szint)}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {AllowedFegyver} from "./allowed-fegyver";
|
|||||||
import {BaseHP} from "./masodlagos_ertekek";
|
import {BaseHP} from "./masodlagos_ertekek";
|
||||||
import {dAny} from "../../shared/domain-models/kockak";
|
import {dAny} from "../../shared/domain-models/kockak";
|
||||||
import {KarakterVarazslat} from "./varazslat";
|
import {KarakterVarazslat} from "./varazslat";
|
||||||
|
import {GetAvailableKepzettsegek} from "./kepzettsegek2E";
|
||||||
|
|
||||||
export interface Karakter2E {
|
export interface Karakter2E {
|
||||||
id?: string,
|
id?: string,
|
||||||
@@ -51,13 +52,15 @@ export const DefaultKarakter: Karakter2E = {
|
|||||||
varazslatok: [],
|
varazslatok: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOsztalyForSzintLepes(szintlepesek: Szintlepes[], osztaly: Osztaly2E, szint: number): Szintlepes[] {
|
function setOsztalyForSzintLepes(karakter: Karakter2E, osztaly: Osztaly2E, szint: number): Szintlepes[] {
|
||||||
|
const szintlepesek = karakter.szintlepesek
|
||||||
const prev = szintlepesek.slice(0, szint-1)
|
const prev = szintlepesek.slice(0, szint-1)
|
||||||
const current : Szintlepes = {
|
const current : Szintlepes = {
|
||||||
...szintlepesek[szint-1],
|
...szintlepesek[szint-1],
|
||||||
osztaly,
|
osztaly,
|
||||||
harcosFegyver: undefined,
|
harcosFegyver: undefined,
|
||||||
kalozKritikus: undefined
|
kalozKritikus: undefined,
|
||||||
|
tolvajExtraKepzettseg: undefined,
|
||||||
}
|
}
|
||||||
const tail = szintlepesek.slice(szint).map(x => {return {...x}})
|
const tail = szintlepesek.slice(szint).map(x => {return {...x}})
|
||||||
|
|
||||||
@@ -117,6 +120,39 @@ function setOsztalyForSzintLepes(szintlepesek: Szintlepes[], osztaly: Osztaly2E,
|
|||||||
tail[i].kalozKritikus = kalozKritAtSzint(kalozSzint)
|
tail[i].kalozKritikus = kalozKritAtSzint(kalozSzint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let tolvajSzint = prev.filter(x => x.osztaly === Osztaly2E.Tolvaj).length
|
||||||
|
const existingTolvajExtraKepzettsegek = szintlepesek
|
||||||
|
.map(x => x.tolvajExtraKepzettseg)
|
||||||
|
.filter(x => x != null) as KepzettsegId[]
|
||||||
|
const tolvajExtraKepzettsegAtSzint = (tSzint: number, atLevelSzintlepesek: Szintlepes[]): (KepzettsegId | undefined) => {
|
||||||
|
if (tSzint !== 5 && tSzint !== 9) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
const extraIndex = tSzint === 5 ? 0 : 1
|
||||||
|
if (existingTolvajExtraKepzettsegek.length > extraIndex) {
|
||||||
|
return existingTolvajExtraKepzettsegek[extraIndex]
|
||||||
|
}
|
||||||
|
return GetAvailableKepzettsegek({
|
||||||
|
szintlepesek: atLevelSzintlepesek,
|
||||||
|
faj: karakter.faj,
|
||||||
|
kepzettsegek: karakter.kepzettsegek,
|
||||||
|
tolvajKepzettsegek: karakter.tolvajKepzettsegek,
|
||||||
|
}, {
|
||||||
|
ignoreClassRestrictions: tSzint === 9,
|
||||||
|
})[0]?.Id
|
||||||
|
}
|
||||||
|
|
||||||
|
if (osztaly === Osztaly2E.Tolvaj) {
|
||||||
|
tolvajSzint++
|
||||||
|
current.tolvajExtraKepzettseg = tolvajExtraKepzettsegAtSzint(tolvajSzint, [...prev, current])
|
||||||
|
}
|
||||||
|
for (let i = 0; i < tail.length; i++) {
|
||||||
|
if (tail[i].osztaly === Osztaly2E.Tolvaj) {
|
||||||
|
tolvajSzint++
|
||||||
|
tail[i].tolvajExtraKepzettseg = tolvajExtraKepzettsegAtSzint(tolvajSzint, [...prev, current, ...tail.slice(0, i+1)])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const HD = BaseHP(osztaly)
|
const HD = BaseHP(osztaly)
|
||||||
if (szint === 1) {
|
if (szint === 1) {
|
||||||
@@ -138,6 +174,6 @@ export function ChangeLvl1Osztaly(karakter: Karakter2E, osztaly: Osztaly2E): Kar
|
|||||||
export function ChangeOsztalyAtSzint(karakter: Karakter2E, osztaly: Osztaly2E, szint: number): Karakter2E {
|
export function ChangeOsztalyAtSzint(karakter: Karakter2E, osztaly: Osztaly2E, szint: number): Karakter2E {
|
||||||
return {
|
return {
|
||||||
...karakter,
|
...karakter,
|
||||||
szintlepesek: setOsztalyForSzintLepes(karakter.szintlepesek, osztaly, szint)
|
szintlepesek: setOsztalyForSzintLepes(karakter, osztaly, szint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,28 @@ describe("Kepzettsegek 2E", () => {
|
|||||||
const actual = GetAvailableKepzettsegek(karakter)
|
const actual = GetAvailableKepzettsegek(karakter)
|
||||||
expect(actual).not.toContain(Kepzettsegek.k_meregkeveres)
|
expect(actual).not.toContain(Kepzettsegek.k_meregkeveres)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("at Tolvaj level 9 extra skill can include class-restricted non-Tolvaj skills", () => {
|
||||||
|
const karakter = {
|
||||||
|
...DefaultKarakter,
|
||||||
|
szintlepesek: [
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6, },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6, },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6, },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6, tulajdonsagNoveles: Tulajdonsag2E.Ugyesseg },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6, tolvajExtraKepzettseg: Kepzettsegek.k_meregkeveres.Id },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6, },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6, },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6, },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const restricted = GetAvailableKepzettsegek(karakter)
|
||||||
|
expect(restricted).not.toContain(Kepzettsegek.k_csillagjoslas)
|
||||||
|
|
||||||
|
const unrestricted = GetAvailableKepzettsegek(karakter, { ignoreClassRestrictions: true })
|
||||||
|
expect(unrestricted).toContain(Kepzettsegek.k_csillagjoslas)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
test("multiclass characters get access to kepzettsegek from all classes", () => {
|
test("multiclass characters get access to kepzettsegek from all classes", () => {
|
||||||
const karakter = {
|
const karakter = {
|
||||||
|
|||||||
@@ -27,9 +27,15 @@ export function GetNumberOfKepzettsegek(t_int: number, faj: Faj2E, max: number =
|
|||||||
return numberOfKepzettseg;
|
return numberOfKepzettseg;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function GetAvailableKepzettsegek(karakter: Pick<Karakter2E, 'szintlepesek' | 'faj' | 'kepzettsegek' | 'tolvajKepzettsegek'>): Kepzettseg[] {
|
export function GetAvailableKepzettsegek(
|
||||||
|
karakter: Pick<Karakter2E, 'szintlepesek' | 'faj' | 'kepzettsegek' | 'tolvajKepzettsegek'>,
|
||||||
|
options?: { ignoreClassRestrictions?: boolean }
|
||||||
|
): Kepzettseg[] {
|
||||||
const osztalyok = new Set(karakter.szintlepesek.map(x => x.osztaly))
|
const osztalyok = new Set(karakter.szintlepesek.map(x => x.osztaly))
|
||||||
const availableKepzettsegek = availableKezpettsegListFajjal(karakter.faj, ...osztalyok)
|
const baseKepzettsegList = options?.ignoreClassRestrictions
|
||||||
|
? KepzettsegLista
|
||||||
|
: availableKezpettsegListFajjal(karakter.faj, ...osztalyok)
|
||||||
|
const availableKepzettsegek = baseKepzettsegList
|
||||||
.filter(k => !karakter.kepzettsegek.includes(k.Id))
|
.filter(k => !karakter.kepzettsegek.includes(k.Id))
|
||||||
|
|
||||||
if (!osztalyok.has(Osztaly2E.Tolvaj)) {
|
if (!osztalyok.has(Osztaly2E.Tolvaj)) {
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
import {ChangeOsztalyAtSzint, DefaultKarakter, Karakter2E} from "./karakter2E";
|
||||||
|
import {Osztaly2E} from "./osztaly2E";
|
||||||
|
import {LevelUp} from "./szintlepes";
|
||||||
|
|
||||||
|
function applyLevelUp(karakter: Karakter2E): Karakter2E {
|
||||||
|
let next: Karakter2E | undefined;
|
||||||
|
LevelUp(karakter, updated => {
|
||||||
|
next = updated;
|
||||||
|
});
|
||||||
|
expect(next).toBeDefined();
|
||||||
|
return next as Karakter2E;
|
||||||
|
}
|
||||||
|
|
||||||
|
function level1Tolvaj(): Karakter2E {
|
||||||
|
return {
|
||||||
|
...DefaultKarakter,
|
||||||
|
szint: 1,
|
||||||
|
szintlepesek: [{
|
||||||
|
osztaly: Osztaly2E.Tolvaj,
|
||||||
|
HProll: 6,
|
||||||
|
}],
|
||||||
|
tolvajKepzettsegek: [],
|
||||||
|
varazslatok: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Harcos specialization in multiclass level-ups", () => {
|
||||||
|
it("adds a specialization when first Harcos level is gained at character level 2", () => {
|
||||||
|
const afterLevel2 = applyLevelUp(level1Tolvaj());
|
||||||
|
const multiclassed = ChangeOsztalyAtSzint(afterLevel2, Osztaly2E.Harcos, 2);
|
||||||
|
|
||||||
|
const secondLevel = multiclassed.szintlepesek[1];
|
||||||
|
expect(secondLevel?.osztaly).toBe(Osztaly2E.Harcos);
|
||||||
|
expect(secondLevel?.harcosFegyver).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not add a specialization on even Harcos class level", () => {
|
||||||
|
const afterLevel2 = applyLevelUp(level1Tolvaj());
|
||||||
|
const multiclassed = ChangeOsztalyAtSzint(afterLevel2, Osztaly2E.Harcos, 2);
|
||||||
|
const afterLevel3 = applyLevelUp(multiclassed);
|
||||||
|
|
||||||
|
const thirdLevel = afterLevel3.szintlepesek[2];
|
||||||
|
expect(thirdLevel?.osztaly).toBe(Osztaly2E.Harcos);
|
||||||
|
expect(thirdLevel?.harcosFegyver).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("adds the next specialization on odd Harcos class level after multiclass", () => {
|
||||||
|
const afterLevel2 = applyLevelUp(level1Tolvaj());
|
||||||
|
const multiclassed = ChangeOsztalyAtSzint(afterLevel2, Osztaly2E.Harcos, 2);
|
||||||
|
const afterLevel3 = applyLevelUp(multiclassed);
|
||||||
|
const afterLevel4 = applyLevelUp(afterLevel3);
|
||||||
|
|
||||||
|
const firstHarcosSpec = multiclassed.szintlepesek[1]?.harcosFegyver;
|
||||||
|
const thirdHarcosLevelSpec = afterLevel4.szintlepesek[3]?.harcosFegyver;
|
||||||
|
|
||||||
|
expect(firstHarcosSpec).toBeDefined();
|
||||||
|
expect(thirdHarcosLevelSpec).toBeDefined();
|
||||||
|
expect(thirdHarcosLevelSpec).not.toBe(firstHarcosSpec);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Tolvaj extra skill in multiclass level-ups", () => {
|
||||||
|
it("adds extra skill when Tolvaj class reaches level 5 at higher character level", () => {
|
||||||
|
const karakter: Karakter2E = {
|
||||||
|
...DefaultKarakter,
|
||||||
|
szint: 5,
|
||||||
|
szintlepesek: [
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6 },
|
||||||
|
{ osztaly: Osztaly2E.Harcos, HProll: 10 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 4 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 5 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 3 },
|
||||||
|
],
|
||||||
|
tolvajKepzettsegek: ["k_alcazas", "k_csapdak", "k_egyensulyozas", "k_hamisitas"],
|
||||||
|
varazslatok: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const afterLevel6 = applyLevelUp(karakter);
|
||||||
|
const sixthLevel = afterLevel6.szintlepesek[5];
|
||||||
|
|
||||||
|
expect(sixthLevel?.osztaly).toBe(Osztaly2E.Tolvaj);
|
||||||
|
expect(sixthLevel?.tolvajExtraKepzettseg).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("recomputes missing extra skill when class change makes current level Tolvaj level 5", () => {
|
||||||
|
const karakter: Karakter2E = {
|
||||||
|
...DefaultKarakter,
|
||||||
|
szint: 5,
|
||||||
|
szintlepesek: [
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 5 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 4 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 3 },
|
||||||
|
{ osztaly: Osztaly2E.Harcos, HProll: 8 },
|
||||||
|
],
|
||||||
|
tolvajKepzettsegek: ["k_alcazas", "k_csapdak", "k_egyensulyozas", "k_hamisitas"],
|
||||||
|
varazslatok: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const changed = ChangeOsztalyAtSzint(karakter, Osztaly2E.Tolvaj, 5);
|
||||||
|
const fifthLevel = changed.szintlepesek[4];
|
||||||
|
|
||||||
|
expect(fifthLevel?.osztaly).toBe(Osztaly2E.Tolvaj);
|
||||||
|
expect(fifthLevel?.tolvajExtraKepzettseg).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("at Tolvaj class level 9 LevelUp can auto-pick a class-restricted non-Tolvaj skill", () => {
|
||||||
|
const karakter: Karakter2E = {
|
||||||
|
...DefaultKarakter,
|
||||||
|
szint: 8,
|
||||||
|
szintlepesek: [
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 5 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 4 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 3 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 2, tolvajExtraKepzettseg: "k_meregkeveres" },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 4 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 5 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 3 },
|
||||||
|
],
|
||||||
|
tolvajKepzettsegek: ["k_alcazas", "k_csapdak", "k_egyensulyozas", "k_hamisitas"],
|
||||||
|
varazslatok: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const afterLevel9 = applyLevelUp(karakter);
|
||||||
|
expect(afterLevel9.szintlepesek[8]?.tolvajExtraKepzettseg).toBe("k_alkimia");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("at Tolvaj class level 9 class-change recomputation can set non-Tolvaj restricted skill", () => {
|
||||||
|
const karakter: Karakter2E = {
|
||||||
|
...DefaultKarakter,
|
||||||
|
szint: 9,
|
||||||
|
szintlepesek: [
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 6 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 5 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 4 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 3 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 2, tolvajExtraKepzettseg: "k_meregkeveres" },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 4 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 5 },
|
||||||
|
{ osztaly: Osztaly2E.Tolvaj, HProll: 3 },
|
||||||
|
{ osztaly: Osztaly2E.Harcos, HProll: 8 },
|
||||||
|
],
|
||||||
|
tolvajKepzettsegek: ["k_alcazas", "k_csapdak", "k_egyensulyozas", "k_hamisitas"],
|
||||||
|
varazslatok: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const changed = ChangeOsztalyAtSzint(karakter, Osztaly2E.Tolvaj, 9);
|
||||||
|
expect(changed.szintlepesek[8]?.tolvajExtraKepzettseg).toBe("k_alkimia");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -67,7 +67,9 @@ export function LevelUp(karakter: Karakter2E, changeKarakter: (input: Karakter2E
|
|||||||
if (autoPickedOsztaly === Osztaly2E.Tolvaj){
|
if (autoPickedOsztaly === Osztaly2E.Tolvaj){
|
||||||
const tolvajSzint = 1 + karakter.szintlepesek.filter(x => x.osztaly === Osztaly2E.Tolvaj).length
|
const tolvajSzint = 1 + karakter.szintlepesek.filter(x => x.osztaly === Osztaly2E.Tolvaj).length
|
||||||
if (tolvajSzint === 5 || tolvajSzint === 9) {
|
if (tolvajSzint === 5 || tolvajSzint === 9) {
|
||||||
const availableKepzettsegek = GetAvailableKepzettsegek(karakter)
|
const availableKepzettsegek = GetAvailableKepzettsegek(karakter, {
|
||||||
|
ignoreClassRestrictions: tolvajSzint === 9,
|
||||||
|
})
|
||||||
szintlepes.tolvajExtraKepzettseg = availableKepzettsegek[0].Id;
|
szintlepes.tolvajExtraKepzettseg = availableKepzettsegek[0].Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ function CreateCharacter2E(props: {
|
|||||||
<h4 className='col align-self-center'>Tanult</h4>
|
<h4 className='col align-self-center'>Tanult</h4>
|
||||||
</div>
|
</div>
|
||||||
<OsztalySelector2E />
|
<OsztalySelector2E />
|
||||||
{karakter.szintlepesek[0].osztaly === Osztaly2E.Harcos && <HarcosFegyverSpecializacio szint={1}/>}
|
{karakter.szintlepesek[0].osztaly === Osztaly2E.Harcos && <HarcosFegyverSpecializacio harcosSzint={1} karakterSzint={1}/>}
|
||||||
<KarakterKepzettsegek />
|
<KarakterKepzettsegek />
|
||||||
<hr/>
|
<hr/>
|
||||||
{/* 1. szinten */}
|
{/* 1. szinten */}
|
||||||
|
|||||||
Reference in New Issue
Block a user