refactor: create structure for backend

This commit is contained in:
2023-10-26 12:05:16 +02:00
parent 42d3cb5b65
commit 7eeef67b29
81 changed files with 491 additions and 48 deletions
@@ -0,0 +1,88 @@
import React from "react";
import {KarakterInputs} from "../domain-models/karakter";
import {SignedNumberToText} from "./Helpers";
import {Mentok, MentoTipus, MentoTipusLabel, MentokTotal} from "../domain-models/mentok";
import {BaseHP, HP} from "../domain-models/masodlagos_ertekek";
import {TamadasBonusz} from "../domain-models/tamadas_bonusz";
function MentoNovekedes(props : {tipus: MentoTipus, ujMentok: Mentok, regiMentok: Mentok}) {
const {tipus, ujMentok, regiMentok} = props
if (ujMentok[tipus] === regiMentok[tipus]) {
return null
}
return <div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label'>{MentoTipusLabel(tipus)} mentő növekedés{' '}</label>
<span className='col col-form-label'>{SignedNumberToText(ujMentok[tipus] - regiMentok[tipus])}</span>
</div>;
}
function UjMento(props : {tipus: MentoTipus, ujMentok: Mentok, regiMentok: Mentok}) {
const {tipus, ujMentok, regiMentok} = props
if (ujMentok[tipus] === regiMentok[tipus]) {
return null
}
return <div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label'>{MentoTipusLabel(tipus)} mentő új értéke{' '}</label>
<span className='col col-form-label'>{SignedNumberToText(ujMentok[tipus])}</span>
</div>;
}
function BasicNewLevel(props: {
karakter: Pick<KarakterInputs, 'osztaly' | 'tulajdonsagok' | 'hpRolls'>
szint: number
changeRolledHP: (hp: number) => void,
}) {
const {karakter, szint, changeRolledHP} = props
const regiMentok = MentokTotal({...karakter, szint: szint - 1})
const ujMentok = MentokTotal({...karakter, szint: szint})
const regiTB = TamadasBonusz(karakter.osztaly, szint-1)
const ujTB = TamadasBonusz(karakter.osztaly, szint)
if (regiTB.length < ujTB.length) {
regiTB.push(0)
}
const TBdiff = ujTB.map((x, i) => x - regiTB[i])
const isTBincreased = TBdiff.length > 0 && TBdiff.some(x => x > 0)
return <>
<div className='row'>
<div className='col-lg-6'>
<div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label'>Plusz dobott HP (d{BaseHP(karakter.osztaly)}){' '}</label>
<div className='col-sm-2 col'>
<input
className='form-control'
maxLength={2}
type='number'
value={karakter.hpRolls[szint-2] || 1}
min={1}
max={12}
onChange={e => changeRolledHP(Number(e.target.value))} />
</div>
</div>
{ isTBincreased && <div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label'>Támadás bónusz növekedés{' '}</label>
<span className='col col-form-label'>{TBdiff.map(SignedNumberToText).join(" / ")}</span>
</div>}
<MentoNovekedes tipus={'kitartas'} ujMentok={ujMentok} regiMentok={regiMentok} />
<MentoNovekedes tipus={'reflex'} ujMentok={ujMentok} regiMentok={regiMentok} />
<MentoNovekedes tipus={'akaratero'} ujMentok={ujMentok} regiMentok={regiMentok} />
</div>
<div className='col-lg-6'>
<div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label'>Új HP{' '}</label>
<span className='col col-form-label'>{HP({...karakter, hpRolls: karakter.hpRolls.slice(0, szint-1)})}</span>
</div>
{isTBincreased && <div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label'>Új Támadás bónusz{' '}</label>
<span className='col col-form-label'>{ujTB.map(SignedNumberToText).join(" / ")}</span>
</div>}
<UjMento tipus={'kitartas'} ujMentok={ujMentok} regiMentok={regiMentok} />
<UjMento tipus={'reflex'} ujMentok={ujMentok} regiMentok={regiMentok} />
<UjMento tipus={'akaratero'} ujMentok={ujMentok} regiMentok={regiMentok} />
</div>
</div>
</>
}
export default BasicNewLevel
@@ -0,0 +1,43 @@
import React from "react";
import {Faj, FajDescription, FajLabel, FajSpecials} from "../domain-models/faj";
function FajSelector(props: { faj: Faj, changeFaj: (val: Faj) => void }) {
const {faj, changeFaj} = props
return <>
<div className='row m-2'>
<label className='col-md-2 col-sm-3 col-form-label'>Faj</label>
<select className='col form-select' value={faj} onChange={e => changeFaj(e.target.value as Faj)}>
<option key={Faj.Ember} value={Faj.Ember}>{FajLabel(Faj.Ember)}</option>
<optgroup label='más emberi népek'>
<option key={Faj.Amazon} value={Faj.Amazon}>{FajLabel(Faj.Amazon)}</option>
<option key={Faj.Birodalmi} value={Faj.Birodalmi}>{FajLabel(Faj.Birodalmi)}</option>
<option key={Faj.Eszaki} value={Faj.Eszaki}>{FajLabel(Faj.Eszaki)}</option>
<option key={Faj.Etuniai} value={Faj.Etuniai}>{FajLabel(Faj.Etuniai)}</option>
<option key={Faj.Osember} value={Faj.Osember}>{FajLabel(Faj.Osember)}</option>
</optgroup>
<optgroup label='nem emberi fajok'>
<option key={Faj.Elf} value={Faj.Elf}>{FajLabel(Faj.Elf)}</option>
<option key={Faj.Felelf} value={Faj.Felelf}>{FajLabel(Faj.Felelf)}</option>
<option key={Faj.Felork} value={Faj.Felork}>{FajLabel(Faj.Felork)}</option>
<option key={Faj.Felszerzet}
value={Faj.Felszerzet}>{FajLabel(Faj.Felszerzet)}</option>
<option key={Faj.Gnom} value={Faj.Gnom}>{FajLabel(Faj.Gnom)}</option>
<option key={Faj.Torpe} value={Faj.Torpe}>{FajLabel(Faj.Torpe)}</option>
</optgroup>
</select>
</div>
<div className='row m-2'>
<label className='col-md-2 col-sm-3 form-label'></label>
<div className='col'>
<p className='row pt-2'>
{FajDescription(faj)}
</p>
<ul>
{FajSpecials(faj).map(((special, i) => (<li key={faj + i}>{special}</li>)))}
</ul>
</div>
</div>
</>
}
export default FajSelector
@@ -0,0 +1,78 @@
import React from "react";
import {Fegyver, KarakterFelszereles, PancelTypeLabel} from "../domain-models/felszereles";
import {Osztaly} from '../domain-models/osztaly'
import {AllowedPancelTypes} from '../domain-models/allowed-pancel-types'
import pancelok from '../domain-models/pancel.json'
import pajzsok from '../domain-models/pajzs.json'
import fegyverek from '../domain-models/fegyver.json'
import {arraySetN} from "../../util";
import {AllowedFegyver} from "../domain-models/allowed-fegyver";
export function FegyverLabel(fegyver: Fegyver): string {
return `${fegyver.Name}${fegyver.Ketkezes ? '+' : ''}${fegyver.Egzotikus ? '(E)' : ''} | ${
fegyver.NumberOfDamageDice}d${fegyver.DamageDice} ${
fegyver.CritRangeStart < 20 ? `${fegyver.CritRangeStart}-20` : ''}x${fegyver.CritMultiplier}${
fegyver.Price > 0 ? ` | ár: ${fegyver.Price} at ` : ''}${
fegyver.Range > 0 ? ` | táv: ${fegyver.Range}` : ''}`
}
function Felszereles(props: {felszereles: KarakterFelszereles, changeFelszereles: (felszereles: KarakterFelszereles) => void, osztaly: Osztaly, harcosSpec: Fegyver['Id'][]}) {
const { felszereles, changeFelszereles, osztaly, harcosSpec } = props;
const allowedPancelTypes = AllowedPancelTypes([osztaly])
const valasztottFegyverek = felszereles.fegyverIDk
.map((id, idx) => ({idx, fegyver: fegyverek.data.find(f => f.Id === id)})).filter((x) => x.fegyver != null).map(({idx, fegyver}) => ({idx, fegyver: fegyver as Fegyver}))
const osztalyAllowedFegyverek = AllowedFegyver(osztaly, harcosSpec)
const allowedFegyverek = [...osztalyAllowedFegyverek, ...valasztottFegyverek.filter(({idx, fegyver}) => !osztalyAllowedFegyverek.map(f => f.Id).includes(fegyver.Id)).map(({fegyver}) => fegyver)]
const changeFegyver = (idx: number, newID: string) => {
const found = fegyverek.data.find(x => x.Id === newID)
if (!found) {
console.log('Nem létező fegyver ID: ', newID)
return
}
changeFelszereles({...felszereles, fegyverIDk: arraySetN(felszereles.fegyverIDk, idx, newID)})
}
return <>
<div className='row'>
<h5 className='col align-self-center'>Felszerelés</h5>
</div>
<div className='row m-2'>
<label className='col-md-2 col-sm-3 col-form-label'>Viselt páncél</label>
<select className='col form-select' value={felszereles.pancelID} onChange={e => changeFelszereles({...felszereles, pancelID: e.target.value === 'nincs' ? undefined : e.target.value})}>
<option key={'nincs'} value={'nincs'}>Nincs</option>
{
allowedPancelTypes.map(pancelType => (
<optgroup key={pancelType} label={PancelTypeLabel(pancelType)}>
{pancelok['pancel'].filter(p => p.Type === pancelType).map(p => <option key={p.Id} value={p.Id}>{`${p.Name} (+${p.VO} VO) - ${p.Price} at`}</option>)}
</optgroup>
))
}
</select>
</div>
<div className='row m-2'>
<label className='col-md-2 col-sm-3 col-form-label'>Hordott pajzs</label>
<select className='col form-select' value={felszereles.pajzsID} onChange={e => changeFelszereles({...felszereles, pajzsID: e.target.value === 'nincs' ? undefined : e.target.value})}>
<option key={'nincs'} value={'nincs'}>Nincs</option>
{allowedPancelTypes.length > 0 && (pajzsok['pajzs'].map(p => <option key={p.Id} value={p.Id}>{`${p.Name} (+${p.VO} VO) - ${p.Price} at`}</option>))}
</select>
</div>
{valasztottFegyverek.map(({idx, fegyver}) => (
<div key={`fegyver-${idx}`} className='row m-2'>
<label className='col-md-2 col-sm-3 col-form-label'>Fegyver</label>
<select className='col form-select' value={fegyver.Id} onChange={e => changeFegyver(idx, e.target.value)}>
<optgroup label="Közelharci">
{allowedFegyverek.filter(f => f.Type === 'kozelharci').map(f => <option key={f.Id} value={f.Id}>{FegyverLabel(f)}</option>)}
</optgroup>
<optgroup label="Távolsági">
{allowedFegyverek.filter(f => f.Type === 'lofegyver').map(f => <option key={f.Id} value={f.Id}>{FegyverLabel(f)}</option>)}
</optgroup>
</select>
<button className='col-md-2 col-sm-3 btn btn-outline-dark btn-lg ms-2' type='button' onClick={() => changeFelszereles({...felszereles, fegyverIDk: [...felszereles.fegyverIDk.slice(0, idx), ...felszereles.fegyverIDk.slice(idx+1)]})}>Elvesz</button>
</div>
))}
<button className='btn btn-outline-dark btn btn-lg ms-2' type='button' onClick={() => changeFelszereles({...felszereles, fegyverIDk: [...felszereles.fegyverIDk, 'okol']})}>Fegyver hozzáadása</button>
</>
}
export default Felszereles
@@ -0,0 +1,38 @@
import React from "react";
import fegyverek from "../domain-models/fegyver.json"
import {defaultFegyverID, GetFegyver} from "../domain-models/felszereles";
function HarcosFegyverSpecializacio(props: {
specialization: string,
existingSpecializations: string[],
changeSpecialization: (specialization: string) => void
szint: number
}) {
const {
specialization,
existingSpecializations,
changeSpecialization,
szint
} = props
const fegyver = GetFegyver(specialization)
const pickableFegyverek = fegyverek.data.filter(f => f.Id === specialization || existingSpecializations.filter(x => x === f.Id).length < (szint < 9 ? 1 : 2))
const kozelharciPickable = pickableFegyverek.filter(f => f.Type === 'kozelharci')
const tavolsagiPickable = pickableFegyverek.filter(f => f.Type === 'lofegyver')
return <>
<div className='row m-2'>
<label className='col-md-2 col-sm-3 col-form-label' >Fegyver specializáció</label>
<select className='col form-select' value={fegyver?.Id || defaultFegyverID} onChange={e => changeSpecialization(e.target.value)}>
<optgroup label="Közelharci">
{kozelharciPickable.map(f => <option key={`spec-${szint}-${f.Id}`} value={f.Id}>{f.Name}</option>)}
</optgroup>
<optgroup label="Távolsági">
{tavolsagiPickable.map(f => <option key={`spec-${szint}-${f.Id}`} value={f.Id}>{f.Name}</option>)}
</optgroup>
</select>
{fegyver == null && <span className='form-field-error'>Ismeretlen fegyver: {specialization}</span>}
</div>
</>
}
export default HarcosFegyverSpecializacio
@@ -0,0 +1,3 @@
export function SignedNumberToText(val: number) : string {
return val === 0 ? " 0" : (val > 0 ? '+'+val : val.toString())
}
@@ -0,0 +1,27 @@
import React from "react";
import {AllJellemIDs, GetJellem, JellemID} from "../domain-models/jellem";
function JellemSelector(props: {selected: JellemID, changeJellem: (val: JellemID) => void}) {
const { selected, changeJellem } = props
const jellem = GetJellem(selected)
return <>
<div className='row m-2'>
<label className='col-md-2 col-sm-3 col-form-label'>Jellem</label>
<select className='col form-select' value={selected} onChange={e => changeJellem(e.target.value as JellemID)}>
{AllJellemIDs.map((id) => (
<option key={id} value={id}>{GetJellem(id).Label}</option>
))}
</select>
</div>
<div className='row m-2'>
<label className='col-md-2 col-sm-3 form-label'></label>
<div className='col'>
<p className='row pt-2'>
{jellem.Description}
</p>
</div>
</div>
</>
}
export default JellemSelector
@@ -0,0 +1,34 @@
import React from "react";
import {Osztaly} from "../domain-models/osztaly";
import {AllowedFegyver} from "../domain-models/allowed-fegyver";
function KalozKritikus(props: {
kritFegyverId: string,
existingKrits: string[],
changeKrit: (krit: string) => void,
szint: number
}) {
const {
kritFegyverId,
existingKrits,
changeKrit,
szint
} = props
const fegyverek = AllowedFegyver(Osztaly.Kaloz, []).filter(f => f.Id === kritFegyverId || existingKrits.filter(x => x === f.Id).length < (szint < 9 ? 1 : 2))
return <>
<div className='row m-2'>
<label className='col-md-2 col-sm-3 col-form-label'>Kritikus</label>
<select className='col form-select' value={kritFegyverId} onChange={e => changeKrit(e.target.value)}>
<optgroup label="Közelharci">
{fegyverek.filter(f => f.Type === 'kozelharci').map(f => <option key={f.Id} value={f.Id}>{f.Name}</option>)}
</optgroup>
<optgroup label="Távolsági">
{fegyverek.filter(f => f.Type === 'lofegyver').map(f => <option key={f.Id} value={f.Id}>{f.Name}</option>)}
</optgroup>
</select>
</div>
</>
}
export default KalozKritikus
@@ -0,0 +1,89 @@
import React from "react";
import KepzettsegSelector from "./KepzettsegSelector";
import {
Kepzettseg,
Kepzettsegek,
KepzettsegId,
TolvajKepzettsegList,
} from "../domain-models/kepzettsegek";
import {arraySetN} from "../../util";
function InternalKepzettsegekSelector(props: {
title: string,
numberOfKepzettseg: number,
getKepzettsegListaN: (n: number) => Kepzettseg[],
kepzettsegek: KepzettsegId[],
changeKepzettsegek: (newKepzettsegek: KepzettsegId[]) => void
}) {
const {title, numberOfKepzettseg, getKepzettsegListaN, kepzettsegek, changeKepzettsegek} = props
const klist = Array.from(new Array(numberOfKepzettseg).keys())
const preCalculated: {
kepzettsegek: Kepzettseg[],
changeKepzettseg: (newKepzettseg: KepzettsegId) => void,
selected: Kepzettseg,
}[] = [];
for (let i = 0; i < numberOfKepzettseg; i++) {
preCalculated.push({
kepzettsegek: getKepzettsegListaN(i),
selected: Kepzettsegek[kepzettsegek[i]],
changeKepzettseg: (newKepzettseg: KepzettsegId) => changeKepzettsegek(arraySetN(kepzettsegek, i, newKepzettseg))
})
}
return <>
<div className='row m-2'>
<label className='col-lg-2 col-md-12 col-form-label'>{title}</label>
<div className='col'>
{klist.map((idx) =>
<KepzettsegSelector
key={title+idx}
kepzettsegek={preCalculated[idx].kepzettsegek}
selected={preCalculated[idx].selected}
changeKepzettseg={preCalculated[idx].changeKepzettseg}
/>)
}
</div>
</div>
</>
}
function KarakterKepzettsegek (props: {
numberOfKepzettsegek: number
kepzettsegek: KepzettsegId[],
changeKepzettsegek: (newKepzettsegek: KepzettsegId[]) => void
tolvajKepzettsegek: KepzettsegId[],
changeTolvajKepzettsegek: (newKepzettsegek: KepzettsegId[]) => void
getKepzettsegListaN: (n: number) => Kepzettseg[]
}) {
const { kepzettsegek, numberOfKepzettsegek, getKepzettsegListaN, changeKepzettsegek, tolvajKepzettsegek, changeTolvajKepzettsegek} = props
// TODO: Birodalmi tolvajnal az Alikmia, vagy Meregkeveres kezelese
const getTolvajKepzettsegListaN = (n: number) : Kepzettseg[] => {
const tolvajKepzettsegekWithoutN = [...tolvajKepzettsegek.slice(0, n), ...tolvajKepzettsegek.slice(n+1)]
return TolvajKepzettsegList.filter(x => !kepzettsegek.includes(x.Id) && !tolvajKepzettsegekWithoutN.includes(x.Id))
}
return <>
<InternalKepzettsegekSelector
title="Képzettségek"
numberOfKepzettseg={numberOfKepzettsegek}
getKepzettsegListaN={getKepzettsegListaN}
changeKepzettsegek={changeKepzettsegek}
kepzettsegek={kepzettsegek} />
{tolvajKepzettsegek.length > 0 && <InternalKepzettsegekSelector
title="Tolvaj képzettségek"
numberOfKepzettseg={4}
getKepzettsegListaN={getTolvajKepzettsegListaN}
changeKepzettsegek={changeTolvajKepzettsegek}
kepzettsegek={tolvajKepzettsegek} />}
</>
}
export default KarakterKepzettsegek
@@ -0,0 +1,32 @@
import React from "react";
import {Kepzettseg, KepzettsegId} from "../domain-models/kepzettsegek";
import {TulajdonsagLabel} from "../domain-models/tulajdonsag";
import {OsztalyLabel} from "../domain-models/osztaly";
function kepzettsegOptionText(k: Kepzettseg) {
const osztalyok = k.Osztalyok?.reduce((acc, o) => acc + ' / ' + OsztalyLabel(o), '')?.substring(3)
return k.Name + ' (' + k.Tulajdonsag.reduce((acc, k) => (acc === '' ? acc : acc + ' / ') + TulajdonsagLabel(k), '') + ')' + (osztalyok == null ? '' : (' - ' + osztalyok));
}
function KepzettsegSelector (props: {kepzettsegek: Kepzettseg[], changeKepzettseg: (newKepzettseg: KepzettsegId) => void, selected : Kepzettseg}) {
const { kepzettsegek, changeKepzettseg, selected } = props
return <>
<div className='row'>
<select className='form-control'
value={selected.Id} onChange={e => changeKepzettseg(e.target.value as KepzettsegId)}>
{kepzettsegek.map(k =>(
<option key={k.Id} value={k.Id}>
{kepzettsegOptionText(k)}
</option>
))}
</select>
</div>
<div className='row pt-2'>
<p className='col'>{selected.Description}</p>
</div>
</>
}
export default KepzettsegSelector
@@ -0,0 +1,106 @@
import React from "react";
import {KarakterInputs} from "../domain-models/karakter";
import BasicNewLevel from "./BasicNewLevel";
import TulajdonsagNoveles from "./TulajdonsagNoveles";
import {Tulajdonsag, TulajdonsagokTotal} from "../domain-models/tulajdonsag";
import {arraySetN} from "../../util";
import {Osztaly} from "../domain-models/osztaly";
import HarcosFegyverSpecializacio from "./HarcosFegyverSpecializacio";
import KalozKritikus from "./KalozKritikus";
function kalozKritIndex(szint: number) {
return Math.floor(szint/3)-1
}
function LevelUp(props: {
szint: number,
karakter: KarakterInputs,
changeTulajdonsagNoveles: (t: Tulajdonsag) => void,
changeRolledHP: (rolledHP: number) => void,
changeHarcosSpec: (spec: string) => void,
changeKalozKritikus: (krit: string) => void,
}) {
const {
szint,
karakter,
changeTulajdonsagNoveles,
changeRolledHP,
changeHarcosSpec,
changeKalozKritikus,
} = props
const specializationIndex = Math.floor((szint-1) / 2)
const specialization = karakter.harcosSpecializaciok[specializationIndex]
const kritIndex = kalozKritIndex(szint)
const krit = karakter.kalozKritikus[kritIndex]
return <div key={`level-up-${szint}`}>
<div className='row mt-3'>
<h5 className='col align-self-center'>{szint}. Szint</h5>
</div>
{szint % 4 === 0 && <TulajdonsagNoveles
tulajdonsagok={karakter.tulajdonsagok}
szint={szint}
tulajdonsagNovelesek={karakter.tulajdonsagNovelesek}
changeTulajdonsagNoveles={changeTulajdonsagNoveles}
/>}
<BasicNewLevel
szint={szint}
karakter={karakter}
changeRolledHP={changeRolledHP}
/>
{karakter.osztaly === Osztaly.Harcos && szint % 2 === 1 &&
<HarcosFegyverSpecializacio
specialization={specialization}
existingSpecializations={karakter.harcosSpecializaciok}
changeSpecialization={changeHarcosSpec}
szint={szint}
/>
}
{karakter.osztaly === Osztaly.Kaloz && szint % 3 === 0 && !!krit &&
<KalozKritikus
kritFegyverId={krit}
existingKrits={karakter.kalozKritikus}
changeKrit={changeKalozKritikus}
szint={szint}
/>
}
</div>
}
export function LevelUps(props: {karakter: KarakterInputs, changeKarakter: (inputs: KarakterInputs) => void}){
const {karakter, changeKarakter} = props;
const tulajdonsagokAtSzint = (szint: number) => TulajdonsagokTotal({...karakter, tulajdonsagNovelesek: karakter.tulajdonsagNovelesek.slice(0, Math.floor(szint / 4))})
const changeRolledHPAtSzint = (szint: number) => (newHProll: number) => {
changeKarakter({...karakter, hpRolls: arraySetN(karakter.hpRolls, szint-2, newHProll)})
console.log(karakter)
}
const changeTulajdonsagNovelesAtSzint = (szint: number) => (t: Tulajdonsag) => { changeKarakter({...karakter, tulajdonsagNovelesek: arraySetN(karakter.tulajdonsagNovelesek, Math.floor((szint / 4)-1), t)}) }
const changeHarcosSpecializacioAtSzint = (szint: number) => (spec: string) => {
changeKarakter({...karakter, harcosSpecializaciok: arraySetN(karakter.harcosSpecializaciok, Math.floor((szint-1) / 2), spec)})
}
const changeKalozKritikusAtSzint = (szint: number) => (krit: string) => {
changeKarakter({...karakter, kalozKritikus: arraySetN(karakter.kalozKritikus, kalozKritIndex(szint), krit)})
}
return <>
{karakter.hpRolls.map((_, i) => i+2).map(szint => <>
<LevelUp
key={`level-up-${szint}`}
szint={szint}
karakter={{...karakter, tulajdonsagok: tulajdonsagokAtSzint(szint)}}
changeTulajdonsagNoveles={changeTulajdonsagNovelesAtSzint(szint)}
changeRolledHP={changeRolledHPAtSzint(szint)}
changeHarcosSpec={changeHarcosSpecializacioAtSzint(szint)}
changeKalozKritikus={changeKalozKritikusAtSzint(szint)}
/>
</>
)}
</>
}
export default LevelUps
@@ -0,0 +1,61 @@
import React from "react";
import {OverlayTrigger, Tooltip} from "react-bootstrap";
import {SignedNumberToText} from "./Helpers";
import {MasodlagosErtekekView} from "../domain-models/masodlagos_ertekek";
function MasodlagosErtekek(props: MasodlagosErtekekView) {
const { HP, VO, CelzoTB, Mentok, KozelharciTB } = props
const tooltip = (
<Tooltip id="tooltip">
<strong>Hentelési Potenciál</strong>
</Tooltip>
);
return <>
<div className='row'>
<h5 className='col align-self-center'>Másodlagos értékek</h5>
</div>
<div className='row'>
<div className='col-lg-6'>
<div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label'>Életerő{' '}
<OverlayTrigger placement='top' overlay={tooltip} delay={0} defaultShow={false} flip={false}>
<span>(HP)</span>
</OverlayTrigger>
</label>
<p className='col col-form-label'>{HP}</p>
</div>
<div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label' >Védekezési Osztály (VO)</label>
<p className='col col-form-label'>{VO}</p>
</div>
<div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label' >Közelharci támadás</label>
<p className='col col-form-label'>{KozelharciTB.map(SignedNumberToText).join(" / ")}</p>
</div>
<div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label' >Célzó támadás</label>
<p className='col col-form-label'>{CelzoTB.map(SignedNumberToText).join(" / ")}</p>
</div>
</div>
<div className='col-lg-6'>
<div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label' >Kitartás mentő</label>
<p className='col col-form-label'>{SignedNumberToText(Mentok.kitartas)}</p>
</div>
<div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label' >Reflex mentő</label>
<p className='col col-form-label'>{SignedNumberToText(Mentok.reflex)}</p>
</div>
<div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label' >Akaraterő mentő </label>
<p className='col col-form-label'>{SignedNumberToText(Mentok.akaratero)}</p>
</div>
</div>
</div>
</>
}
export default MasodlagosErtekek
@@ -0,0 +1,67 @@
import React from "react";
import {
Osztaly,
OsztalyDescription,
OsztalyLabel,
OsztalyProperties,
OsztalySpecialSkills
} from "../domain-models/osztaly";
import {Faj, SzintKorlatokFajokra} from "../domain-models/faj";
function OsztalySelector(props: {currentFaj: Faj, currentOsztaly: Osztaly, changeOsztaly: (newOsztaly: Osztaly) => void}) {
const {currentFaj, currentOsztaly, changeOsztaly} = props;
return <>
<div className='row m-2'>
<label className='col-md-2 col-sm-3 col-form-label'>Osztály</label>
<select className="col form-select" value={currentOsztaly} onChange={(e) => changeOsztaly(e.target.value as Osztaly)} >
<optgroup label='Harcos'>
<option value={Osztaly.Harcos}>{OsztalyLabel(Osztaly.Harcos)}</option>
{SzintKorlatokFajokra(currentFaj)[Osztaly.Amazon] > 0 && (
<option value={Osztaly.Amazon}>{OsztalyLabel(Osztaly.Amazon)}</option>) }
<option value={Osztaly.Barbar}>{OsztalyLabel(Osztaly.Barbar)}</option>
<option value={Osztaly.Ijasz}>{OsztalyLabel(Osztaly.Ijasz)}</option>
<option value={Osztaly.Kaloz}>{OsztalyLabel(Osztaly.Kaloz)}</option>
</optgroup>
<option value={Osztaly.Pap}>{OsztalyLabel(Osztaly.Pap)}</option>
{SzintKorlatokFajokra(currentFaj)[Osztaly.Tolvaj] > 0 && (<option value={Osztaly.Tolvaj}>{OsztalyLabel(Osztaly.Tolvaj)}</option>)}
{SzintKorlatokFajokra(currentFaj)[Osztaly.Varazslo] > 0 && (
<optgroup label='Varázsló'>
<option value={Osztaly.Varazslo}>{OsztalyLabel(Osztaly.Varazslo)}</option>
<option value={Osztaly.Illuzionista}>{OsztalyLabel(Osztaly.Illuzionista)}</option>
</optgroup>
)}
</select>
</div>
<div className='row m-2'>
<label className='col-md-2 col-sm-3 form-label'></label>
<div className='col' >
<p className='row pt-2'>
{OsztalyDescription(currentOsztaly)}
</p>
<ul>
{OsztalyProperties(currentOsztaly).map(((special, i) => (<li key={currentOsztaly + i}>{special}</li>)))}
</ul>
<div className='col'>
{OsztalySpecialSkills(currentOsztaly).map(skill =>
<div key={skill.Id} >
<strong className='d-inline'>
{skill.Name}
</strong>
{' '}
{skill.Description}
{skill.ExtendedDescription && (
<ol>
{skill.ExtendedDescription.map((ext, i) =>
(<li key={skill.Id + '-' + i}>{ext}</li>))}
</ol>
)}
</div>
)}
</div>
</div>
</div>
</>
}
export default OsztalySelector;
@@ -0,0 +1,52 @@
import React from "react";
import {Faj, FajLabel} from "../domain-models/faj";
import {Modifier} from "../domain-models/tulajdonsag";
import {SignedNumberToText} from "./Helpers";
function fajiModositoText(faj: Faj, szamolas: (f: Faj) => number) : string {
const mod = szamolas(faj)
return (mod !== 0) ? SignedNumberToText(mod) + ' (' + FajLabel(faj) + ')' : ''
}
function TulajdonsagInput(props: {
tulajdonsag: string,
currentFaj : Faj,
fajiModosito: (faj: Faj) => number,
changeValue: (val: number) => void
currentValue: number
tooLowError: string,
tooHighError: string
}) {
const {
tulajdonsag,
changeValue,
currentFaj,
currentValue,
fajiModosito,
tooLowError,
tooHighError,
} = props;
return (<div className='row m-2'>
<label className='col-lg-1 col-sm-2 col-form-label'>{tulajdonsag}</label>
<div className='col-lg-1 col-sm-2 m-2'>
<input className='form-control' maxLength={2} type='number' value={currentValue} onChange={e => changeValue(Number(e.target.value))} />
</div>
<span className='col-sm-2 m-2'>
{fajiModositoText(currentFaj, fajiModosito)}
</span>
<span className='col-sm-2 m-2'>
Összesen: { (currentValue + (fajiModosito(currentFaj))).toString() }
</span>
<span className='col-sm-2 m-2'>
Módosító: { SignedNumberToText(Modifier(currentValue + fajiModosito(currentFaj))) }
</span>
{currentValue < 3 && (
<span className='form-field-error'>{tooLowError}</span>)}
{currentValue > 18 && (
<span className='form-field-error'>{tooHighError}</span>)}
</div>)
}
export default TulajdonsagInput;
@@ -0,0 +1,38 @@
import React from "react";
import {
KarakterTulajdonsagok,
Modifier,
Tulajdonsag,
TulajdonsagIDs,
TulajdonsagLabel
} from "../domain-models/tulajdonsag";
import {SignedNumberToText} from "./Helpers";
function TulajdonsagNoveles(props: {tulajdonsagok: KarakterTulajdonsagok, szint: number, tulajdonsagNovelesek: Tulajdonsag[], changeTulajdonsagNoveles: (tulajdonsag: Tulajdonsag) => void}) {
const {tulajdonsagok, szint, tulajdonsagNovelesek, changeTulajdonsagNoveles} = props
const tulajdonsagNoveles = tulajdonsagNovelesek[(szint / 4)-1]
return <>
<div className='row'>
<div className='col-lg-6'>
<div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label'>Tulajdonság növelés{' '}</label>
<div className='col'>
<select className='form-select' value={tulajdonsagNoveles} onChange={(e) => changeTulajdonsagNoveles(e.target.value as Tulajdonsag)}>
{TulajdonsagIDs.filter(t => t === tulajdonsagNoveles || tulajdonsagok[t] < 18).map(t => (
<option value={t} key={t}>{TulajdonsagLabel(t)}</option>
))}
</select>
</div>
</div>
</div>
<div className='col-lg-6'>
<div className='row m-2'>
<label className='col-sm-6 col-8 col-form-label'>Új {TulajdonsagLabel(tulajdonsagNoveles)}{' '}</label>
<span className='col col-form-label'>{tulajdonsagok[tulajdonsagNoveles]} ({SignedNumberToText(Modifier(tulajdonsagok[tulajdonsagNoveles]))})</span>
</div>
</div>
</div>
</>
}
export default TulajdonsagNoveles
@@ -0,0 +1,84 @@
import React from "react";
import {
KarakterTulajdonsagok,
RollAllAbilities,
Tulajdonsag,
TulajdonsagModositokFajokra
} from "../domain-models/tulajdonsag";
import TulajdonsagInput from "./TulajdonsagInput";
import {Faj} from "../domain-models/faj";
function Tulajdonsagok(props: {
currentFaj: Faj,
tulajdonsagok: KarakterTulajdonsagok
changeTulajdonsagok: (tulajdonsagok: KarakterTulajdonsagok) => void
}) {
const {currentFaj, tulajdonsagok, changeTulajdonsagok} = props
return <>
<div className='row'>
<h5 className='col-lg-2 col-sm-4 align-self-center'>Tulajdonságok</h5>
<div className='col-sm-2 m-2'>
<button className='btn btn-dark' type='button'
onClick={() => changeTulajdonsagok(RollAllAbilities())}>Dobás
</button>
</div>
</div>
<TulajdonsagInput
tulajdonsag='Erő'
currentValue={tulajdonsagok.t_ero}
currentFaj={currentFaj}
fajiModosito={TulajdonsagModositokFajokra(Tulajdonsag.Ero)}
changeValue={(val: number) => changeTulajdonsagok({...tulajdonsagok, t_ero: val})}
tooLowError='Túl gyenge vagy, nem bírtad felemelni a kezed a jelentkezéshez!'
tooHighError='Szét szakadtak az izmaid!'
/>
<TulajdonsagInput
tulajdonsag='Ügyesség'
currentValue={tulajdonsagok.t_ugy}
currentFaj={currentFaj}
fajiModosito={TulajdonsagModositokFajokra(Tulajdonsag.Ugyesseg)}
changeValue={(val: number) => changeTulajdonsagok({...tulajdonsagok, t_ugy: val})}
tooLowError='Orrabuktál jelentkezés helyett!'
tooHighError='Emberfeletti zsonglörködésedre záptojással válaszoltak a helyiek!'
/>
<TulajdonsagInput
tulajdonsag='Egészség'
currentValue={tulajdonsagok.t_egs}
currentFaj={currentFaj}
fajiModosito={TulajdonsagModositokFajokra(Tulajdonsag.Egeszseg)}
changeValue={(val: number) => changeTulajdonsagok({...tulajdonsagok, t_egs: val})}
tooLowError='Túl beteg vagy ahhoz, hogy kalandozni menj!'
tooHighError='Kicsattanó egészségedet csak a diambroid állíthatja meg, minő véletlen, hogy pont az arcodba robbant...'
/>
<TulajdonsagInput
tulajdonsag='Intelligencia'
currentValue={tulajdonsagok.t_int}
currentFaj={currentFaj}
fajiModosito={TulajdonsagModositokFajokra(Tulajdonsag.Intelligencia)}
changeValue={(val: number) => changeTulajdonsagok({...tulajdonsagok, t_int: val})}
tooLowError='Elfelejtetted, hogy mikor is kéne kalandozni indulni!'
tooHighError='Ilyen tudás és logika birtokában mi szükséged van új információkra? Mindent le tudsz vezetni a már meglévő ismereteidből, és ezt azonnal beláttad.'
/>
<TulajdonsagInput
tulajdonsag='Bölcsesség'
currentValue={tulajdonsagok.t_bol}
currentFaj={currentFaj}
fajiModosito={TulajdonsagModositokFajokra(Tulajdonsag.Bolcsesseg)}
changeValue={(val: number) => changeTulajdonsagok({...tulajdonsagok, t_bol: val})}
tooLowError='Nem bírtál ellenállni a kíváncsiságodnak, hogy közelebbről is megvizsgáld a tőr hegyét. Nagyon közelről.'
tooHighError='Hatalmas bölcsességedben beláttad a kalandozás veszélyeit és inkább más tevékenységbe fogtál.'
/>
<TulajdonsagInput
tulajdonsag='Karizma'
currentValue={tulajdonsagok.t_kar}
currentFaj={currentFaj}
fajiModosito={TulajdonsagModositokFajokra(Tulajdonsag.Karizma)}
changeValue={(val: number) => changeTulajdonsagok({...tulajdonsagok, t_kar: val})}
tooLowError='Mintha taszítanád az embereket, sose sikerült kalandozó csapatot találnod.'
tooHighError='Az ellenkező nem tagjai nem engedték, hogy útnak indulj.'
/>
</>
}
export default Tulajdonsagok