epic: first try at adding a backend
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App faro={undefined}/>);
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import './App.css';
|
||||
import CreateCharacter from "./first-edition/pages/CreateCharacter";
|
||||
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
||||
import {Faro} from "@grafana/faro-web-sdk";
|
||||
|
||||
function App(props: {faro?: Faro}) {
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: "/",
|
||||
element: <CreateCharacter faro={props.faro} />,
|
||||
},
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className='container'>
|
||||
<RouterProvider router={router} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -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
|
||||
@@ -0,0 +1,24 @@
|
||||
import {Fegyver, GetFegyver} from "./felszereles";
|
||||
import fegyverDB from "./fegyver.json";
|
||||
import {Osztaly} from "./osztaly";
|
||||
|
||||
export function AllowedFegyver(o: Osztaly, harcosSpec: string[]): Fegyver[] {
|
||||
const fegyverek = fegyverDB.data.map(x => x as Fegyver)
|
||||
const nemEgzotikus = fegyverek.filter(f => !f.Egzotikus)
|
||||
const varazslo = fegyverek.filter(f => ['okol', 'bot', 'bunko', 'tor', 'parittya', 'dobotu'].includes(f.Id))
|
||||
const tolvaj = fegyverek.filter(f => ['okol', 'tor', 'parittya', 'rovid_ij', 'dobotu', 'konnyu_szamszerij', 'nehez_szamszerij', 'szablya', 'hosszu_kard', 'rovid_kard' ].includes(f.Id))
|
||||
switch (o) {
|
||||
case Osztaly.Harcos:
|
||||
const harcosSpecFegyverek = harcosSpec.map(GetFegyver).filter(x => x != null && x.Egzotikus).map(x => x as Fegyver)
|
||||
return [...nemEgzotikus, ...harcosSpecFegyverek]
|
||||
case Osztaly.Amazon:
|
||||
case Osztaly.Barbar:
|
||||
case Osztaly.Kaloz: return nemEgzotikus;
|
||||
case Osztaly.Ijasz: return [...nemEgzotikus, fegyverDB.data.find(f => f.Id === 'visszacsapo_ij') as Fegyver]
|
||||
// Note: Isteni fegyver barmi lehet istentol foggoen
|
||||
case Osztaly.Pap: return fegyverek;
|
||||
case Osztaly.Tolvaj: return tolvaj;
|
||||
case Osztaly.Illuzionista:
|
||||
case Osztaly.Varazslo: return varazslo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import {PancelType} from "./felszereles";
|
||||
import {Osztaly} from "./osztaly";
|
||||
|
||||
export function AllowedPancelTypes(osztalyok: Osztaly[]): PancelType[] {
|
||||
return [...new Set(osztalyok.flatMap(osztalyAllowedPancelTypes))]
|
||||
}
|
||||
|
||||
function osztalyAllowedPancelTypes(o: Osztaly): PancelType[] {
|
||||
switch (o) {
|
||||
case Osztaly.Amazon: return ['konnyu'];
|
||||
case Osztaly.Barbar: return ['konnyu', 'kozepes', 'nehez'];
|
||||
case Osztaly.Pap: return ['konnyu', 'kozepes', 'nehez'];
|
||||
case Osztaly.Illuzionista: return [];
|
||||
case Osztaly.Varazslo: return [];
|
||||
case Osztaly.Harcos: return ['konnyu', 'kozepes', 'nehez'];
|
||||
case Osztaly.Ijasz: return ['konnyu', 'kozepes'];
|
||||
case Osztaly.Kaloz: return ['konnyu', 'kozepes'];
|
||||
case Osztaly.Tolvaj: return ['konnyu']
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
import {
|
||||
KarakterTulajdonsagok,
|
||||
Tulajdonsag,
|
||||
TulajdonsagModositokFajokra,
|
||||
} from "./tulajdonsag";
|
||||
import {Osztaly} from "./osztaly";
|
||||
|
||||
|
||||
export enum Faj {
|
||||
Ember = 'f_ember',
|
||||
Amazon = 'f_amazon',
|
||||
Birodalmi = 'f_birodalmi',
|
||||
Etuniai = 'f_etuniai',
|
||||
Eszaki = 'f_eszaki',
|
||||
Osember = 'f_osember',
|
||||
Elf = 'f_elf',
|
||||
Felelf = 'f_felelf',
|
||||
Felork = 'f_felork',
|
||||
Felszerzet = 'f_felszerzet',
|
||||
Gnom = 'f_gnom',
|
||||
Torpe = 'f_torpe',
|
||||
}
|
||||
|
||||
export function FajLabel(faj: Faj) : string {
|
||||
switch (faj) {
|
||||
case Faj.Ember: return 'Ember';
|
||||
case Faj.Amazon: return 'Amazon';
|
||||
case Faj.Birodalmi: return 'Birodalmi';
|
||||
case Faj.Etuniai: return 'Etúniai';
|
||||
case Faj.Eszaki: return 'Északi';
|
||||
case Faj.Osember: return 'Ősember';
|
||||
case Faj.Elf: return 'Elf';
|
||||
case Faj.Felelf: return 'Félelf';
|
||||
case Faj.Felork: return 'Félork';
|
||||
case Faj.Felszerzet: return 'Félszerzet';
|
||||
case Faj.Gnom: return 'Gnóm';
|
||||
case Faj.Torpe: return 'Törpe';
|
||||
}
|
||||
}
|
||||
|
||||
export function FajDescription(faj: Faj) : string {
|
||||
switch (faj) {
|
||||
case Faj.Ember: return "Az emberi népek sokfélesége és szaporasága, valamint a bennük élő felfedezői hajlam és erkölcsi rugalmasság hatására képviselőik majdnem minden földön megtalálhatók. A legtöbb ember a lenti vonásokkal rendelkezik.";
|
||||
case Faj.Amazon: return "Bár az amazonok népe igen kis létszámú, harciasságuk miatt mégis félik őket. Az amazonok nyúlánk termetűek, hajuk általában vöröses vagy világosbarna, bőrük világos. Társadalmukban teljes a nőuralom, a férfiakat rabszolgaságban tartják és megtiltják számukra a fegyverviselést. Képzett tengeri rablók, de a szárazföldön is megállják a helyüket. Az amazon nők kivétel nélkül értenek a harchoz és soha, soha nem hagyják megtorlatlanul az őket ért sérelmeket. Technikailag fejletlenek. Kis erejű passzív pszionikus (elmebeli) képességeik vannak.";
|
||||
case Faj.Birodalmi: return "Bár a Birodalom történelemelőtti kora már évezredek óta elmúlt, a nép maradékai még megtalálhatók. Az irántuk érzett gyűlölet miatt sokan rejtőzködni kényszerülnek közülük, pedig hatalmuk már meg sem közelíti a régit – életüket többnyire dekadens élvezetek habzsolásával, kábítószeres mámorban töltik. Bőrük lilás, a tisztavérűek esetén padlizsánszínű, szemük ibolyaszín. A fajtiszta birodalmiak között a beltenyészet és a degeneráció miatt gyakoriak az örökletes betegségek. Városaik számtalan titkot és mesés kincseket rejtenek.";
|
||||
case Faj.Etuniai: return "Az etúniai lovas nomádok kultúrája mindmáig megőrizte primitívségét. Akár földművelésből, akár lovas portyázásból, akár rablásból és kereskedésből élnek, nem fogékonyak a finomságok iránt. Eszközeik is egyszerűek: fegyvereik főleg hosszú lándzsák, és bár kedvelik a kardokat és láncvérteket, nem jeleskednek azok előállításában (a vas megmunkálását kovácsaik féltett titokként őrzik). Többnyire semleges jelleműek – bár azok, akik otthonuktól elszakadva kénytelenek megélni, inkább a gonosz felé hajlanak. Az etúniaiak középtermetűek, bőrük cserzett, hajuk olajos fekete, amit leggyakrabban copfban fognak össze. A férfiak kedvelik a bajusz viseletét.";
|
||||
case Faj.Eszaki: return "Az északi kultúra lételeme a harc és a hajózás. Még nőik is kiválóan forgatják a harci fejszét vagy a hosszú élű bárdot, s – bár rabszolgatartók – kegyetlenségnek tartják rabszolgáikat a legelemibb védekező eszközöktől, mint a késtől vagy a rövidkardtól megfosztani vagy fegyvertelenekre támadni. Ettől eltekintve vérszomjasak és általában semleges vagy gonosz jelleműek. Testalkatuk magas és erős, hajuk vöröses, szőke vagy világosbarna. A férfiak szakállat vagy bajuszt, a nők hosszú hajat viselnek. A déli vidékeken civilizálatlanságuk és faragatlanságuk miatt gyakran megvetik őket.";
|
||||
case Faj.Osember: return "Az Ősemberek vad földek primitív őslakói. Máig merizték görnyedt tartásukat, szőrös küllemüket és loboncos fekete hajukat. A fémmegmunkálást még sokan nem ismerik, s kőeszközöket – esetleg rezet– használnak. Írásuk egyáltalán nincs. Félisteneént tisztelik hátasaikat, a hatalmas mamutokat.";
|
||||
case Faj.Elf: return "Az elfek szépségükről, hosszú életükről és fejlett civilizációjukról ismertek, amely ötvözi a városi és természeti élet előnyeit. Termetük nyúlánk, vonásaik az embernél finomabbak, de egyben törékenyebbek. Kiváló íjászok és varázslók. Általában visszahúzódóak, csak ritkán lépnek kapcsolatba a rövidebb életű népekkel – legjobban az emberekkel és a félszerzetekkel jönnek ki. Jellemük általában kaotikus jó.";
|
||||
case Faj.Felelf: return "A félelfek elf és ember szülők gyermekei. Kis számuk miatt nem alkotnak külön közösségeket.";
|
||||
case Faj.Felork: return "A félorkok többsége külsejében inkább rút emberre hasonlít (bár termetük gyakran görnyedt, arcvonásaik pedig a disznóéra emlékeztetnek), belsőleg azonban számos ork vonással rendelkeznek: számítók, magányosak és bizalmatlanok a szebb fajokkal, de legtöbbször fajtársaikkal is. Különösen sok közöttük az orgyilkos és a közönséges gonosztevő; egyikük-másikuk ezt némi mágikus erővel vegyíti. A legtöbb félork gonosz jellemű.";
|
||||
case Faj.Felszerzet: return "A félszerzetek általában megelégszenek a nyugodt vidéki élettel. Termetük az emberi fele. Hajlamosak az elhízásra, s lábukat vastag szőr borítja. Általában mezítláb járnak. Mivel lusták és kényelemszeretők, csak ritkán adják fejüket kalandokra – ekkor azonban kiváló tolvajokká válhatnak.";
|
||||
case Faj.Gnom: return "A gnómok különösen ritka, elsősorban emberi városokban megtalálható alacsony termetű faj. A gnómokat alacsony termetükről, vékony végtagjaikról és tömpe, húsos orrukról lehet fölismerni. A gnómok jó kézművesek és van érzékük a mágiához is – elsősorban az illuzionisták trükkjeihez vonzódnak.";
|
||||
case Faj.Torpe: return "A törpék elsősorban hegyek között és dombvidékeken élnek. Termetük kicsi (1,2 m), de testük tömzsi és igen szívós. Bozontos szakállat viselnek, amely a férfiak esetén dús és sörteszerű, a nőknél finomabb és ritkásabb. A törpék kiemelkedőek a mindenféle mesterségekben, különösen a fémmunkákban, de harcban is megállják helyüket. Nagy nemzetségekbe szerveződnek és híresek igazságérzetükről, makacsságukról és kapzsiságukról. A legtöbb törpe törvényes jó vagy törvényes semleges jellemű.";
|
||||
}
|
||||
}
|
||||
|
||||
export function FajSpecials(faj : Faj) : string[] {
|
||||
switch (faj) {
|
||||
case Faj.Ember: return [
|
||||
"A játék kezdetén egy extra képzettséggel kezdenek",
|
||||
"Korlátlanul fejlődhetnek minden osztályban",
|
||||
];
|
||||
case Faj.Amazon: return [
|
||||
"Ha két vagy több amazon együttesen harcol, VO-juk 2-vel nő pszionikus képességeik miatt",
|
||||
"Szintkorlátok: Harcos -, Pap 5, Tolvaj 0, Varázsló 0",
|
||||
];
|
||||
case Faj.Birodalmi: return [
|
||||
"+1 Int, -1 Egs",
|
||||
"Egyik kezdő képzettségük mindenképpen az Alkímia vagy a Méregkeverés",
|
||||
"Szintkorlátok: Harcos 7, Pap 5, Tolvaj 5, Varázsló -",
|
||||
];
|
||||
case Faj.Etuniai: return [
|
||||
"+1 Egs, -1 Böl",
|
||||
"Az egyik kezdő képzettségük mindenképpen a Lovaglás",
|
||||
"Szintkorlátok: Harcos -, Pap 5, Tolvaj -, Varázsló 4",
|
||||
];
|
||||
case Faj.Eszaki: return [
|
||||
"+1 Erő, -1 Böl",
|
||||
"Az egyik kezdő képzettségük mindenképpen a Hajózás",
|
||||
"Szintkorlátok: Harcos -, Pap 7, Tolvaj -, Varázsló 5",
|
||||
];
|
||||
case Faj.Osember: return [
|
||||
"+1 Erő, +1 Egészség, -1 Int, -1 Böl",
|
||||
"Szintkorlátok: Harcos -, Pap 5, Tolvaj 4, Varázsló 0",
|
||||
];
|
||||
case Faj.Elf: return [
|
||||
"+1 Ügy, -1 Egs",
|
||||
"Immunisak az altató mágiára, +2 mentődobás bűbáj ellen",
|
||||
"Automatikusan képzettek az íjak és a hosszúkard használatában akkor is, ha osztályuk ezt nem adná meg nekik",
|
||||
"Nem támaszthatók föl közönséges mágiával",
|
||||
"Szintkorlátok: Harcos 9, Pap 7, Tolvaj 6, Varázsló 9",
|
||||
];
|
||||
case Faj.Felelf: return [
|
||||
"Automatikusan képzettek az íjak és a hosszúkard használatában",
|
||||
"Szintkorlátok: Harcos 9, Pap 5, Tolvaj 9, Varázsló 9",
|
||||
];
|
||||
case Faj.Felork: return [
|
||||
"+1 Erő, +1 Egs, -2 Kar",
|
||||
"Szintkorlátok: Harcos 9, Pap 5, Tolvaj 9, Varázsló 5",
|
||||
];
|
||||
case Faj.Felszerzet: return [
|
||||
"+1 Ügy, -1 Erő",
|
||||
"+1 VO kis méretük miatt",
|
||||
"+1 támadást kapnak dobófegyverekre és parittyákra",
|
||||
"Szintkorlátok: Harcos 6, Pap 6, Tolvaj 9, Varázsló 4",
|
||||
];
|
||||
case Faj.Gnom: return [
|
||||
"+1 Int, -1 Erő",
|
||||
"Szintkorlátok: Harcos 6, Pap 6, Tolvaj 8, Varázsló 7",
|
||||
];
|
||||
case Faj.Torpe: return [
|
||||
"+1 Egs, -1 Kar",
|
||||
"Lassabban mozognak az embereknél (alapsebességük 20’)",
|
||||
"+2 mentődobást kapnak mérgek és varázslatok hatásai ellen",
|
||||
"Szintkorlátok: Harcos 9, Pap 9, Tolvaj 6, Varázsló 4",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
export type Szintkorlatok = Record<Osztaly, number>
|
||||
|
||||
export interface FajDetails {
|
||||
ID: Faj,
|
||||
Label: string,
|
||||
Description: string,
|
||||
Specials: string[],
|
||||
TulajdonsagModifiers: KarakterTulajdonsagok
|
||||
Szintkorlatok: Szintkorlatok
|
||||
}
|
||||
|
||||
|
||||
export function GetFajDetails(faj: Faj): FajDetails {
|
||||
return {
|
||||
ID: faj,
|
||||
Label: FajLabel(faj),
|
||||
Description: FajDescription(faj),
|
||||
Specials: FajSpecials(faj),
|
||||
TulajdonsagModifiers: fajiTulajdonsagModositok(faj),
|
||||
Szintkorlatok: SzintKorlatokFajokra(faj),
|
||||
}
|
||||
}
|
||||
|
||||
function fajiTulajdonsagModositok(faj: Faj): KarakterTulajdonsagok {
|
||||
return {
|
||||
[Tulajdonsag.Ero]: TulajdonsagModositokFajokra(Tulajdonsag.Ero)(faj),
|
||||
[Tulajdonsag.Ugyesseg]: TulajdonsagModositokFajokra(Tulajdonsag.Ugyesseg)(faj),
|
||||
[Tulajdonsag.Egeszseg]: TulajdonsagModositokFajokra(Tulajdonsag.Egeszseg)(faj),
|
||||
[Tulajdonsag.Intelligencia]: TulajdonsagModositokFajokra(Tulajdonsag.Intelligencia)(faj),
|
||||
[Tulajdonsag.Bolcsesseg]: TulajdonsagModositokFajokra(Tulajdonsag.Bolcsesseg)(faj),
|
||||
[Tulajdonsag.Karizma]: TulajdonsagModositokFajokra(Tulajdonsag.Karizma)(faj),
|
||||
}
|
||||
}
|
||||
|
||||
const EmberiSzintKorlatok: Szintkorlatok = {
|
||||
o_amazon: 0,
|
||||
o_barbar: 20,
|
||||
o_harcos: 20,
|
||||
o_ijasz: 20,
|
||||
o_illuzionista: 20,
|
||||
o_kaloz: 20,
|
||||
o_pap: 20,
|
||||
o_tolvaj: 20,
|
||||
o_varazslo: 20
|
||||
|
||||
}
|
||||
|
||||
// noinspection OverlyComplexFunctionJS,FunctionTooLongJS
|
||||
export function SzintKorlatokFajokra(faj: Faj) : Szintkorlatok {
|
||||
let szintkorlatok = {...EmberiSzintKorlatok}
|
||||
switch (faj) {
|
||||
case Faj.Ember: break;
|
||||
case Faj.Amazon:
|
||||
szintkorlatok.o_pap = 5
|
||||
szintkorlatok.o_tolvaj = 0
|
||||
szintkorlatok.o_illuzionista = 0
|
||||
szintkorlatok.o_varazslo = 0
|
||||
szintkorlatok.o_amazon = 20
|
||||
break
|
||||
case Faj.Birodalmi:
|
||||
szintkorlatok.o_harcos = 7
|
||||
szintkorlatok.o_barbar = 7
|
||||
szintkorlatok.o_ijasz = 7
|
||||
szintkorlatok.o_kaloz = 7
|
||||
szintkorlatok.o_pap = 5
|
||||
szintkorlatok.o_tolvaj = 5
|
||||
break
|
||||
case Faj.Eszaki:
|
||||
case Faj.Etuniai:
|
||||
szintkorlatok.o_pap = 7
|
||||
szintkorlatok.o_illuzionista = 5
|
||||
szintkorlatok.o_varazslo = 5
|
||||
break
|
||||
case Faj.Osember:
|
||||
szintkorlatok.o_pap = 7
|
||||
szintkorlatok.o_tolvaj = 4
|
||||
szintkorlatok.o_illuzionista = 0
|
||||
szintkorlatok.o_varazslo = 0
|
||||
break
|
||||
case Faj.Elf:
|
||||
szintkorlatok.o_pap = 7
|
||||
szintkorlatok.o_tolvaj = 6
|
||||
szintkorlatok.o_illuzionista = 9
|
||||
szintkorlatok.o_varazslo = 9
|
||||
szintkorlatok.o_harcos = 9
|
||||
szintkorlatok.o_barbar = 9
|
||||
szintkorlatok.o_ijasz = 9
|
||||
szintkorlatok.o_kaloz = 9
|
||||
break
|
||||
case Faj.Felelf:
|
||||
szintkorlatok.o_pap = 5
|
||||
szintkorlatok.o_tolvaj = 9
|
||||
szintkorlatok.o_illuzionista = 9
|
||||
szintkorlatok.o_varazslo = 9
|
||||
szintkorlatok.o_harcos = 9
|
||||
szintkorlatok.o_barbar = 9
|
||||
szintkorlatok.o_ijasz = 9
|
||||
szintkorlatok.o_kaloz = 9
|
||||
break
|
||||
case Faj.Felork:
|
||||
szintkorlatok.o_pap = 5
|
||||
szintkorlatok.o_tolvaj = 9
|
||||
szintkorlatok.o_illuzionista = 5
|
||||
szintkorlatok.o_varazslo = 5
|
||||
szintkorlatok.o_harcos = 9
|
||||
szintkorlatok.o_barbar = 9
|
||||
szintkorlatok.o_ijasz = 9
|
||||
szintkorlatok.o_kaloz = 9
|
||||
break
|
||||
case Faj.Felszerzet:
|
||||
szintkorlatok.o_pap = 6
|
||||
szintkorlatok.o_tolvaj = 9
|
||||
szintkorlatok.o_illuzionista = 4
|
||||
szintkorlatok.o_varazslo = 4
|
||||
szintkorlatok.o_harcos = 6
|
||||
szintkorlatok.o_barbar = 6
|
||||
szintkorlatok.o_ijasz = 6
|
||||
szintkorlatok.o_kaloz = 6
|
||||
break
|
||||
case Faj.Gnom:
|
||||
szintkorlatok.o_pap = 6
|
||||
szintkorlatok.o_tolvaj = 8
|
||||
szintkorlatok.o_illuzionista = 7
|
||||
szintkorlatok.o_varazslo = 7
|
||||
szintkorlatok.o_harcos = 6
|
||||
szintkorlatok.o_barbar = 6
|
||||
szintkorlatok.o_ijasz = 6
|
||||
szintkorlatok.o_kaloz = 6
|
||||
break
|
||||
case Faj.Torpe:
|
||||
szintkorlatok.o_pap = 9
|
||||
szintkorlatok.o_tolvaj = 6
|
||||
szintkorlatok.o_illuzionista = 4
|
||||
szintkorlatok.o_varazslo = 4
|
||||
szintkorlatok.o_harcos = 9
|
||||
szintkorlatok.o_barbar = 9
|
||||
szintkorlatok.o_ijasz = 9
|
||||
szintkorlatok.o_kaloz = 9
|
||||
break
|
||||
}
|
||||
return szintkorlatok
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"Id": "alabard",
|
||||
"Name": "Alabárd és más szálfegyverek",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": true,
|
||||
"Price": 10,
|
||||
"DamageDice": 10,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 3,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "bot",
|
||||
"Name": "Bot",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 0,
|
||||
"DamageDice": 6,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "bunko",
|
||||
"Name": "Bunkó",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 0,
|
||||
"DamageDice": 6,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "buzogany",
|
||||
"Name": "Buzogány és láncos buzogány",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 8,
|
||||
"DamageDice": 8,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "csatabard",
|
||||
"Name": "Csatabárd",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 10,
|
||||
"DamageDice": 8,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 3,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "csatabard_2",
|
||||
"Name": "Kétkezes csatabárd",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 20,
|
||||
"DamageDice": 12,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 3,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "csakany",
|
||||
"Name": "Csákány",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 5,
|
||||
"DamageDice": 6,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 4,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "darda",
|
||||
"Name": "Dárda",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": true,
|
||||
"Price": 10,
|
||||
"DamageDice": 8,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 3,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "fejsze",
|
||||
"Name": "Fejsze",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 6,
|
||||
"DamageDice": 6,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 3,
|
||||
"Range": 10
|
||||
},
|
||||
{
|
||||
"Id": "torpe_fejsze",
|
||||
"Name": "Törpe fejsze",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": true,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 30,
|
||||
"DamageDice": 10,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 3,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "handzsar",
|
||||
"Name": "Handzsár",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 50,
|
||||
"DamageDice": 4,
|
||||
"NumberOfDamageDice": 2,
|
||||
"CritRangeStart": 18,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "harci_kalapacs",
|
||||
"Name": "Harci kalapács",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 12,
|
||||
"DamageDice": 8,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 3,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "harci_kalapacs_2",
|
||||
"Name": "Kétkezes harci kalapács",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 25,
|
||||
"DamageDice": 10,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 3,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "fattyu_kard",
|
||||
"Name": "Fattyú kard",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": true,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 35,
|
||||
"DamageDice": 10,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 19,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "rovid_kard",
|
||||
"Name": "Rövid kard",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 10,
|
||||
"DamageDice": 6,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 19,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "hosszu_kard",
|
||||
"Name": "Hosszú kard",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 15,
|
||||
"DamageDice": 8,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 19,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "kard_2",
|
||||
"Name": "Kétkezes kard",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 50,
|
||||
"DamageDice": 6,
|
||||
"NumberOfDamageDice": 2,
|
||||
"CritRangeStart": 19,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "kasza",
|
||||
"Name": "Kasza",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": true,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 18,
|
||||
"DamageDice": 4,
|
||||
"NumberOfDamageDice": 2,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 4,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "landzsa",
|
||||
"Name": "Lándzsa",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 5,
|
||||
"DamageDice": 8,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 20
|
||||
},
|
||||
{
|
||||
"Id": "sarlo",
|
||||
"Name": "Sarló",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 3,
|
||||
"DamageDice": 6,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "szablya",
|
||||
"Name": "Szablya",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 15,
|
||||
"DamageDice": 6,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 18,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "szigony",
|
||||
"Name": "Háromágú szigony",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 10,
|
||||
"DamageDice": 8,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 10
|
||||
},
|
||||
{
|
||||
"Id": "tor",
|
||||
"Name": "Tőr",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 2,
|
||||
"DamageDice": 4,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 19,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 10
|
||||
},
|
||||
{
|
||||
"Id": "ostor",
|
||||
"Name": "Ostor",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": true,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 1,
|
||||
"DamageDice": 3,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
{
|
||||
"Id": "okol",
|
||||
"Name": "Ököl",
|
||||
"Type": "kozelharci",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 0,
|
||||
"DamageDice": 4,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 0
|
||||
},
|
||||
|
||||
{
|
||||
"Id": "dobodarda",
|
||||
"Name": "Dobódárda",
|
||||
"Type": "lofegyver",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 0.1,
|
||||
"DamageDice": 6,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 30
|
||||
},
|
||||
{
|
||||
"Id": "dobotu",
|
||||
"Name": "Dobótű",
|
||||
"Type": "lofegyver",
|
||||
"Ketkezes": false,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 0.5,
|
||||
"DamageDice": 4,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 20
|
||||
},
|
||||
{
|
||||
"Id": "rovid_ij",
|
||||
"Name": "Rövid íj",
|
||||
"Type": "lofegyver",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 30,
|
||||
"DamageDice": 6,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 3,
|
||||
"Range": 60
|
||||
},
|
||||
{
|
||||
"Id": "hosszu_ij",
|
||||
"Name": "Hosszú íj",
|
||||
"Type": "lofegyver",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 75,
|
||||
"DamageDice": 8,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 3,
|
||||
"Range": 70
|
||||
},
|
||||
{
|
||||
"Id": "visszacsapo_ij",
|
||||
"Name": "Visszacsapó íj",
|
||||
"Type": "lofegyver",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": true,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 100,
|
||||
"DamageDice": 8,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 3,
|
||||
"Range": 110
|
||||
},
|
||||
{
|
||||
"Id": "parittya",
|
||||
"Name": "Parittya",
|
||||
"Type": "lofegyver",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 0,
|
||||
"DamageDice": 4,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 20,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 50
|
||||
},
|
||||
{
|
||||
"Id": "konnyu_szamszerij",
|
||||
"Name": "Könnyű számszeríj",
|
||||
"Type": "lofegyver",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 35,
|
||||
"DamageDice": 8,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 19,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 80
|
||||
},
|
||||
{
|
||||
"Id": "nehez_szamszerij",
|
||||
"Name": "Nehéz számszeríj",
|
||||
"Type": "lofegyver",
|
||||
"Ketkezes": true,
|
||||
"Egzotikus": false,
|
||||
"Rohamfelfogo": false,
|
||||
"Price": 50,
|
||||
"DamageDice": 10,
|
||||
"NumberOfDamageDice": 1,
|
||||
"CritRangeStart": 19,
|
||||
"CritMultiplier": 2,
|
||||
"Range": 120
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,419 @@
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"Id": "acel_es_kova",
|
||||
"Name": "Acél és kova",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.1
|
||||
},
|
||||
{
|
||||
"Id": "aso",
|
||||
"Name": "Ásó",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
{
|
||||
"Id": "vas_bogracs",
|
||||
"Name": "Bogrács, vas",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.5
|
||||
},
|
||||
{
|
||||
"Id": "borostomlo",
|
||||
"Name": "Borostömlő",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
{
|
||||
"Id": "csakany",
|
||||
"Name": "Csákány",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 5
|
||||
},
|
||||
{
|
||||
"Id": "elelem",
|
||||
"Name": "Élelem, tartós úti, egy napra",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.5
|
||||
},
|
||||
{
|
||||
"Id": "faklya",
|
||||
"Name": "Fáklya",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.01
|
||||
},
|
||||
|
||||
{
|
||||
"Id": "farud",
|
||||
"Name": "Farúd, 10’",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.03
|
||||
},
|
||||
{
|
||||
"Id": "feszitovas",
|
||||
"Name": "Feszítővas",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 2
|
||||
},
|
||||
{
|
||||
"Id": "fustulo",
|
||||
"Name": "Füstölő, rúd",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
{
|
||||
"Id": "gyertya_viasz",
|
||||
"Name": "Gyertya, viasz",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.1
|
||||
},
|
||||
{
|
||||
"Id": "halasz_halo",
|
||||
"Name": "Háló, halász, 5’*5’",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 4
|
||||
},
|
||||
{
|
||||
"Id": "hatizsak",
|
||||
"Name": "Hátizsák",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 2
|
||||
},
|
||||
{
|
||||
"Id": "hordo_kicsi",
|
||||
"Name": "Hordó, kicsi",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 2
|
||||
},
|
||||
{
|
||||
"Id": "illatszer",
|
||||
"Name": "Illatszer",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 5
|
||||
},
|
||||
{
|
||||
"Id": "kotel_kender_50",
|
||||
"Name": "Kötél, kender, 50’",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
{
|
||||
"Id": "kotel_selyem_50",
|
||||
"Name": "Kötél, selyem, 50’",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 10
|
||||
},
|
||||
{
|
||||
"Id": "kreta",
|
||||
"Name": "Kréta",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.01
|
||||
},
|
||||
{
|
||||
"Id": "lada_fa_kicsi",
|
||||
"Name": "Láda, fa, kicsi",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 2
|
||||
},
|
||||
{
|
||||
"Id": "lada_fa_nagy",
|
||||
"Name": "Láda, fa, nagy",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 5
|
||||
},
|
||||
{
|
||||
"Id": "lada_vas_kicsi",
|
||||
"Name": "Láda, vas, kicsi",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 9
|
||||
},{
|
||||
"Id": "lada_vas_nagy",
|
||||
"Name": "Láda, vas, nagy",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 28
|
||||
},
|
||||
{
|
||||
"Id": "lakat_egyszeru",
|
||||
"Name": "Lakat, egyszerű",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 20
|
||||
},
|
||||
{
|
||||
"Id": "lakat_kivalo",
|
||||
"Name": "Lakat, kiváló",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 80
|
||||
},
|
||||
{
|
||||
"Id": "olaj_lampa_egyszeru",
|
||||
"Name": "Lámpa, olaj, egyszerű",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
|
||||
{
|
||||
"Id": "olaj_lampa_vedett",
|
||||
"Name": "Lámpa, olaj, védett",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 7
|
||||
},
|
||||
{
|
||||
"Id": "olaj_lampa_nagy",
|
||||
"Name": "Lámpa, olaj, nagy",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 12
|
||||
},
|
||||
{
|
||||
"Id": "lanc_10",
|
||||
"Name": "Lánc, 10’",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 10
|
||||
},
|
||||
{
|
||||
"Id": "maszovas",
|
||||
"Name": "Mászóvas",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
{
|
||||
"Id": "olaj_palck",
|
||||
"Name": "Olaj, palack",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
{
|
||||
"Id": "palack_cserep",
|
||||
"Name": "Palack, cserép",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.03
|
||||
},
|
||||
{
|
||||
"Id": "palack_uveg",
|
||||
"Name": "Palack, üveg",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 2
|
||||
},
|
||||
{
|
||||
"Id": "papir",
|
||||
"Name": "Papír, lap",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.4
|
||||
},
|
||||
{
|
||||
"Id": "pecsetgyuru",
|
||||
"Name": "Pecsétgyűrű",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 8
|
||||
},
|
||||
{
|
||||
"Id": "pecsetviasz",
|
||||
"Name": "Pecsétviasz",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
{
|
||||
"Id": "pergamen",
|
||||
"Name": "Pergamen, lap",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.2
|
||||
},
|
||||
{
|
||||
"Id": "sator",
|
||||
"Name": "Sátor",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 10
|
||||
},
|
||||
{
|
||||
"Id": "sav",
|
||||
"Name": "Sav",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 10
|
||||
},
|
||||
{
|
||||
"Id": "szappan",
|
||||
"Name": "Szappan",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.5
|
||||
},
|
||||
{
|
||||
"Id": "szentelt_viz",
|
||||
"Name": "Szenteltvíz",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 25
|
||||
},
|
||||
{
|
||||
"Id": "szog",
|
||||
"Name": "Szög",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.01
|
||||
},
|
||||
{
|
||||
"Id": "takaro",
|
||||
"Name": "Takaró",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.2
|
||||
},
|
||||
{
|
||||
"Id": "tarsoly",
|
||||
"Name": "Tarsoly",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
{
|
||||
"Id": "tegez",
|
||||
"Name": "Tegez",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 2
|
||||
},
|
||||
{
|
||||
"Id": "telercstarto",
|
||||
"Name": "Tekercstartó",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 5
|
||||
},
|
||||
{
|
||||
"Id": "tinta",
|
||||
"Name": "Tinta",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 8
|
||||
},
|
||||
{
|
||||
"Id": "tukor",
|
||||
"Name": "Tükör",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 10
|
||||
},
|
||||
{
|
||||
"Id": "uvegcse",
|
||||
"Name": "Üvegcse",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
{
|
||||
"Id": "vodor",
|
||||
"Name": "Vödör",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.5
|
||||
},
|
||||
{
|
||||
"Id": "zsak",
|
||||
"Name": "Zsák",
|
||||
"Type": "simple",
|
||||
"PriceInGold": 0.1
|
||||
},
|
||||
{
|
||||
"Id": "elokelo_ruha",
|
||||
"Name": "Előkelő",
|
||||
"Type": "clothes",
|
||||
"PriceInGold": 75
|
||||
},
|
||||
{
|
||||
"Id": "elokelo_ruha",
|
||||
"Name": "Előkelő",
|
||||
"Type": "clothes",
|
||||
"PriceInGold": 75
|
||||
},
|
||||
{
|
||||
"Id": "kozrendu_ruha",
|
||||
"Name": "Közrendű",
|
||||
"Type": "clothes",
|
||||
"PriceInGold": 0.1
|
||||
},
|
||||
{
|
||||
"Id": "meleg_ruha",
|
||||
"Name": "Meleg",
|
||||
"Type": "clothes",
|
||||
"PriceInGold": 8
|
||||
},
|
||||
{
|
||||
"Id": "mesterember_ruha",
|
||||
"Name": "Mesterember",
|
||||
"Type": "clothes",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
{
|
||||
"Id": "nagyuri_ruha",
|
||||
"Name": "Nagyúri",
|
||||
"Type": "clothes",
|
||||
"PriceInGold": 200
|
||||
},
|
||||
{
|
||||
"Id": "papi_ruha",
|
||||
"Name": "Papi",
|
||||
"Type": "clothes",
|
||||
"PriceInGold": 5
|
||||
},
|
||||
{
|
||||
"Id": "utazo_ruha",
|
||||
"Name": "Utazó",
|
||||
"Type": "clothes",
|
||||
"PriceInGold": 1
|
||||
},
|
||||
{
|
||||
"Id": "alkimista_labor",
|
||||
"Name": "Alkimista labor",
|
||||
"Type": "special",
|
||||
"PriceInGold": 500
|
||||
},
|
||||
{
|
||||
"Id": "homokora",
|
||||
"Name": "Homokóra",
|
||||
"Type": "special",
|
||||
"PriceInGold": 25
|
||||
},
|
||||
{
|
||||
"Id": "merleg",
|
||||
"Name": "Mérleg",
|
||||
"Type": "special",
|
||||
"PriceInGold": 2
|
||||
},
|
||||
{
|
||||
"Id": "nagyito",
|
||||
"Name": "Nagyító",
|
||||
"Type": "special",
|
||||
"PriceInGold": 100
|
||||
},
|
||||
{
|
||||
"Id": "szent_szimbolum",
|
||||
"Name": "Szent szimbólum",
|
||||
"Type": "special",
|
||||
"PriceInGold": 25
|
||||
},
|
||||
{
|
||||
"Id": "tavcso",
|
||||
"Name": "Távcső",
|
||||
"Type": "special",
|
||||
"PriceInGold": 1000
|
||||
},
|
||||
{
|
||||
"Id": "tolvajszerszamok",
|
||||
"Name": "Tolvajszerszámok",
|
||||
"Type": "special",
|
||||
"PriceInGold": 30
|
||||
},
|
||||
{
|
||||
"Id": "varazskomponens_tarto",
|
||||
"Name": "Varázskomponenstartó",
|
||||
"Type": "special",
|
||||
"PriceInGold": 5
|
||||
},
|
||||
{
|
||||
"Id": "varazskonyv",
|
||||
"Name": "Varázskönyv, üres",
|
||||
"Type": "special",
|
||||
"PriceInGold": 15
|
||||
},
|
||||
{
|
||||
"Id": "vizora",
|
||||
"Name": "Vízóra",
|
||||
"Type": "special",
|
||||
"PriceInGold": 500
|
||||
},
|
||||
{
|
||||
"Id": "zeneszerszam",
|
||||
"Name": "Zeneszerszám, egyszerű",
|
||||
"Type": "special",
|
||||
"PriceInGold": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import pancelok from './pancel.json'
|
||||
import pajzsok from './pajzs.json'
|
||||
import fegyverek from './fegyver.json'
|
||||
|
||||
export type PancelType = 'konnyu' | 'kozepes' | 'nehez'
|
||||
|
||||
export const PancelTypes: PancelType[] = ['konnyu', 'kozepes', 'nehez']
|
||||
|
||||
export interface Pancel {
|
||||
Id: string,
|
||||
Name: string,
|
||||
Type: PancelType
|
||||
VO: number,
|
||||
Price: number,
|
||||
}
|
||||
|
||||
export interface Pajzs {
|
||||
Id: string,
|
||||
Name: string,
|
||||
Type: 'pajzs'
|
||||
VO: number,
|
||||
Price: number,
|
||||
}
|
||||
|
||||
export interface Fegyver {
|
||||
Id: string,
|
||||
Name: string,
|
||||
Type: 'kozelharci' | 'lofegyver'
|
||||
Ketkezes: boolean,
|
||||
Egzotikus: boolean,
|
||||
Rohamfelfogo: boolean,
|
||||
Price: number,
|
||||
DamageDice: number,
|
||||
NumberOfDamageDice: number,
|
||||
CritRangeStart: number,
|
||||
CritMultiplier: number,
|
||||
Range: number
|
||||
}
|
||||
|
||||
export interface KarakterFelszereles {
|
||||
pancelID?: string
|
||||
pajzsID?: string
|
||||
fegyverIDk: string[]
|
||||
}
|
||||
|
||||
export const DefaultFelszereles: KarakterFelszereles = {
|
||||
fegyverIDk: [],
|
||||
}
|
||||
|
||||
export function PancelTypeLabel(type: PancelType): string {
|
||||
let result: string
|
||||
switch(type) {
|
||||
case 'konnyu':
|
||||
result = 'Könnyű'
|
||||
break
|
||||
case 'kozepes':
|
||||
result = 'Közepes'
|
||||
break
|
||||
case 'nehez':
|
||||
result = 'Nehéz'
|
||||
break
|
||||
default:
|
||||
result = 'Egyéb páncél'
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export function GetPancel(id?: string): Pancel | undefined {
|
||||
if (id == null) {
|
||||
return undefined
|
||||
}
|
||||
const filteredPancel = pancelok['pancel'].filter(p => p.Id === id) as Pancel[]
|
||||
return filteredPancel.length > 0 ? filteredPancel[0] : undefined
|
||||
}
|
||||
|
||||
export function MaxAbilityVO(p: PancelType) {
|
||||
switch(p){
|
||||
case 'konnyu': return 3;
|
||||
case 'kozepes': return 2;
|
||||
case 'nehez': return 1;
|
||||
default: return 9999;
|
||||
}
|
||||
}
|
||||
|
||||
export function GetPajzs(id?: string): Pajzs | undefined {
|
||||
if (id == null) {
|
||||
return undefined
|
||||
}
|
||||
const filtered = pajzsok['pajzs'].filter(p => p.Id === id) as Pajzs[]
|
||||
return filtered.length > 0 ? filtered[0] : undefined
|
||||
}
|
||||
|
||||
export function GetFegyver(id: string): Fegyver | undefined {
|
||||
return fegyverek.data.find(f => f.Id === id) as Fegyver | undefined
|
||||
}
|
||||
|
||||
export function GetFegyverek(ids: string[]): Fegyver[] {
|
||||
return ids.map(GetFegyver).filter(x => x != null).map(x => x as Fegyver)
|
||||
}
|
||||
export const defaultFegyverID = 'okol'
|
||||
export const defaultFegyver = GetFegyver('okol')!
|
||||
@@ -0,0 +1,59 @@
|
||||
export type JellemID = 'TJ' | 'SJ' | 'KJ' | 'TS' | 'S' | 'KS' | 'TG' | 'SG' | 'KG'
|
||||
|
||||
export const AllJellemIDs: JellemID[] = ['TJ', 'SJ', 'KJ', 'TS', 'S', 'KS', 'TG', 'SG', 'KG']
|
||||
|
||||
export interface Jellem {
|
||||
ID: JellemID
|
||||
Label: string
|
||||
Description: string
|
||||
}
|
||||
|
||||
export function GetJellem(id: JellemID): Jellem {
|
||||
switch (id) {
|
||||
case "TJ": return {
|
||||
ID: "TJ",
|
||||
Label: "Törvényes Jó",
|
||||
Description: "A törvényes jó karakterek betartják és fontosnak tartják az igazságos törvényeket, valamint a kiérdemelt tekintély tiszteletét. Viselkedésükben lehetőleg egyenesek, és nem okoznak szükségtelen károkat másnak; továbbá segítenek a kevésbé szerencséseken.",
|
||||
}
|
||||
case "SJ": return {
|
||||
ID: "SJ",
|
||||
Label: "Semleges Jó",
|
||||
Description: "A semleges jó karakterek általában jóindulatúak, de nem jellemző rájuk sem a törvényes jók szigora, sem a kaotikus jók kiszámíthatatlansága.",
|
||||
}
|
||||
case "KJ": return {
|
||||
ID: "KJ",
|
||||
Label: "Kaotikus Jó",
|
||||
Description: "A kaotikus jó karakterek nagy súlyt fektetnek az egyéni szabadságra és a jótéteményekre – akkor is, ha ezek a nézetek és tettek ellentétesek a társadalmi szokásokkal és írott törvényekkel.",
|
||||
}
|
||||
case "TS": return {
|
||||
ID: "TS",
|
||||
Label: "Törvényes Semleges",
|
||||
Description: "A törvényes semleges karakterek szigorúan betartják a törvényeket és adott szavukat, de ez a törvénytisztelet nem altruizmusból, hanem elsősorban önzésből, közömbösségből vagy a törvények öncélú tiszteletéből fakad.",
|
||||
}
|
||||
case "S": return {
|
||||
ID: "S",
|
||||
Label: "Semleges",
|
||||
Description: "A semleges karakterek vagy nem törődnek a fontos erkölcsi kérdésekkel – azaz nem kötelezik el magukat egyes ügyek mellett – vagy éppen ellenkezőleg, aktívan a különféle nézetek közötti egyensúlyra és harmóniára törekednek. Az átlagemberek többsége ehhez a jellemhez tartozik.",
|
||||
}
|
||||
case "KS": return {
|
||||
ID: "KS",
|
||||
Label: "Kaotikus Semleges",
|
||||
Description: "A kaotikus semleges karakterek kiszámíthatatlanok, saját boldogulásukra törekednek akár mások ellenében is. A kalandozók igen jelentős része kaotikus semleges jellemű"
|
||||
}
|
||||
case "TG": return {
|
||||
ID: "TG",
|
||||
Label: "Törvényes Gonosz",
|
||||
Description: "A törvényes gonosz karakterek lételeme a törvényadta lehetőségek kihasználása mások kisemmizésére és önmaguk gyarapítására. Nem csoda, hogy számos zsarnok és kiskirály e jellem képviselője.",
|
||||
}
|
||||
case "SG": return {
|
||||
ID: "SG",
|
||||
Label: "Semleges Gonosz",
|
||||
Description: "A semleges gonosz karakterek döntően aljasak és rosszindulatúak, s céljaikat hol a törvények kijátszásával, hol a rájuk való hivatkozással érik el."
|
||||
}
|
||||
case "KG": return {
|
||||
ID: "KG",
|
||||
Label: "Kaotikus Gonosz",
|
||||
Description: "A kaotikus gonosz karakterek kíméletlenül, mindenen és mindenkin átgázolva hajszolják a hatalmat vagy a vagyont, s ennek érdekében bármilyen gaztettre képesek."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import {Faj} from "./faj";
|
||||
import {Osztaly} from "./osztaly";
|
||||
import {KarakterTulajdonsagok, Tulajdonsag, TulajdonsagDefaults} from "./tulajdonsag";
|
||||
import {KepzettsegId} from "./kepzettsegek";
|
||||
import {JellemID} from "./jellem";
|
||||
import { DefaultFelszereles, KarakterFelszereles } from './felszereles'
|
||||
|
||||
export interface KarakterInputs {
|
||||
name: string,
|
||||
nem?: string,
|
||||
kor: number,
|
||||
jellem: JellemID,
|
||||
isten?: string,
|
||||
faj: Faj,
|
||||
osztaly: Osztaly,
|
||||
tulajdonsagok: KarakterTulajdonsagok,
|
||||
kepzettsegek: KepzettsegId[],
|
||||
tolvajKepzettsegek?: KepzettsegId[]
|
||||
szint: number
|
||||
hpRolls: number[],
|
||||
tulajdonsagNovelesek: Tulajdonsag[],
|
||||
harcosSpecializaciok: string[],
|
||||
kalozKritikus: string[],
|
||||
felszereles: KarakterFelszereles,
|
||||
}
|
||||
|
||||
export const KarakterDefaults: KarakterInputs = {
|
||||
name: "Névtelen Kalandozó",
|
||||
faj: Faj.Ember,
|
||||
kor: 20,
|
||||
jellem: 'S',
|
||||
tulajdonsagok: TulajdonsagDefaults,
|
||||
osztaly: Osztaly.Kaloz,
|
||||
kepzettsegek: [],
|
||||
szint: 1,
|
||||
hpRolls: [],
|
||||
tulajdonsagNovelesek: [],
|
||||
harcosSpecializaciok: [],
|
||||
kalozKritikus: [],
|
||||
felszereles: DefaultFelszereles,
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
import {Modifier, Tulajdonsag} from "./tulajdonsag";
|
||||
import {Osztaly} from "./osztaly";
|
||||
import {Faj} from "./faj";
|
||||
import {KarakterInputs} from "./karakter";
|
||||
|
||||
export type KepzettsegId = 'k_alkimia' | 'k_alcazas' | 'k_allatidomitas' | 'k_csapdak' | 'k_csillagjoslas' | 'k_egyensulyozas' | 'k_eloadas' | 'k_ertekbecsles' | 'k_gyogyitas' | 'k_hajozas' | 'k_hallgatozas' | 'k_hamisitas' | 'k_jelek_olvasasa' | 'k_koncentracio' | 'k_lovaglas' | 'k_maszas' | 'k_megfigyeles' | 'k_meregkeveres' | 'k_mesterseg' | 'k_nyomkereses' | 'k_osonas' | 'k_rejtozes' | 'k_szabadulomuveszet' | 'k_tudas' | 'k_ugras' | 'k_uszas' | 'k_varazslatismeret' | 'k_zarnyitas' | 'k_zsebmetszes'
|
||||
|
||||
export interface Kepzettseg {
|
||||
Id: KepzettsegId,
|
||||
Name: string,
|
||||
Description: string,
|
||||
Tulajdonsag: Tulajdonsag[],
|
||||
Osztalyok?: Osztaly[],
|
||||
}
|
||||
|
||||
export const KepzettsegLista: Kepzettseg[] = [
|
||||
{
|
||||
Id: 'k_alkimia',
|
||||
Name: 'Alkímia',
|
||||
Description: 'Különféle különleges anyagok, pl. savak, görögtűz, stb. kikeverésére szolgál. Használatához gyakran jól felszerelt laboratórium szükséges. Az Alkímia képzettséggel a karakter képes beazonosítani a különféle vegyi anyagokat és mérgeket, bizonyos esetekben varázsitalokat is.',
|
||||
Tulajdonsag: [Tulajdonsag.Intelligencia],
|
||||
Osztalyok: [Osztaly.Varazslo, Osztaly.Illuzionista],
|
||||
},
|
||||
{
|
||||
Id: 'k_alcazas',
|
||||
Name: 'Álcázás',
|
||||
Description: 'Álöltözetek készítése és effektív használata. Próbadobást akkor kell dobni, ha az álca hitelességét valaki kétségbe vonhatja (általában titkos dobás; az eredményt csak a mesélő ismeri).',
|
||||
Tulajdonsag: [Tulajdonsag.Karizma],
|
||||
Osztalyok: [Osztaly.Tolvaj],
|
||||
},
|
||||
{
|
||||
Id: 'k_allatidomitas',
|
||||
Name: 'Állatidomítás',
|
||||
Description: 'Állatok megszelídítésére, betanítására szolgál. A járatos karakter próbát tehet arra is, hogy a különféle vadállatok ne tekintsék ellenségüknek vagy prédájuknak',
|
||||
Tulajdonsag: [Tulajdonsag.Karizma],
|
||||
},
|
||||
{
|
||||
Id: 'k_csapdak',
|
||||
Name: 'Csapdák állítása',
|
||||
Description: 'A karakter a rendelkezésre álló idő és alapanyagok függvényében készíthet szimpla vagy komplex csapdákat. Ha egy csapda eltávolítására tett próba sikertelen, az bizonyos eséllyel kisülhet és veszélybe sodorhatja az óvatlan próbálkozót.',
|
||||
Tulajdonsag: [Tulajdonsag.Ugyesseg],
|
||||
Osztalyok: [Osztaly.Tolvaj],
|
||||
},
|
||||
{
|
||||
Id: 'k_csillagjoslas',
|
||||
Name: 'Csillagjóslás',
|
||||
Description: 'A karakter a képzettséggel egyrészt képes meghatározni a karakterek hozzávetőleges pozícióját a térképen, másrészt egyszerűbb jóslatokat készíthet.',
|
||||
Tulajdonsag: [Tulajdonsag.Bolcsesseg],
|
||||
Osztalyok: [Osztaly.Varazslo, Osztaly.Illuzionista],
|
||||
},
|
||||
{
|
||||
Id: 'k_egyensulyozas',
|
||||
Name: 'Egyensúlyozás',
|
||||
Description: 'Omlatag talajon vagy keskeny járófelületen való átjutáshoz szükséges képzettség. Ha a próba sikertelen, a karakter lezuhan.',
|
||||
Tulajdonsag: [Tulajdonsag.Ugyesseg],
|
||||
Osztalyok: [Osztaly.Tolvaj],
|
||||
},
|
||||
{
|
||||
Id: 'k_eloadas',
|
||||
Name: 'Előadás',
|
||||
Description: 'A képzettséggel rendelkező karakter járatos a hangszerek használatában, éneklésben, eposzmondásban, stb.',
|
||||
Tulajdonsag: [Tulajdonsag.Karizma],
|
||||
},
|
||||
{
|
||||
Id: 'k_ertekbecsles',
|
||||
Name: 'Értékbecslés',
|
||||
Description: 'Sikeres próba esetén a karakter hozzávetőlegesen felméri egy tárgy pénzbeli értékét és kiszúrja a hamisítványokat.',
|
||||
Tulajdonsag: [Tulajdonsag.Intelligencia],
|
||||
},
|
||||
{
|
||||
Id: 'k_gyogyitas',
|
||||
Name: 'Gyógyítás',
|
||||
Description: 'A sebek ellátásának, mérgek és betegségek semlegesítésének vagy enyhítésének tudománya. Ha a képzettséget sikeresen alkalmazzák közvetlenül harc után, a bekötözött karakter visszanyer 1d4 elvesztett Hp-t.',
|
||||
Tulajdonsag: [Tulajdonsag.Bolcsesseg],
|
||||
},
|
||||
{
|
||||
Id: 'k_hajozas',
|
||||
Name: 'Hajózás',
|
||||
Description: 'A karakter ismeri a hajózás trükkjeit, tehát elkormányoz kisebb vitorlásokat vagy gályákat, tudja hogyan kell elkerülni a zátonyokat, képes javításokat végezni, stb.',
|
||||
Tulajdonsag: [Tulajdonsag.Ugyesseg],
|
||||
},
|
||||
{
|
||||
Id: 'k_hallgatozas',
|
||||
Name: 'Hallgatózás',
|
||||
Description: 'Alig hallható zajok, beszéd meghallása.',
|
||||
Tulajdonsag: [Tulajdonsag.Bolcsesseg],
|
||||
},
|
||||
{
|
||||
Id: 'k_hamisitas',
|
||||
Name: 'Hamisítás',
|
||||
Description: 'A képzettséggel hamis pénz, iratok, pecsétek és értéktárgyak készíthetők. Próbadobást akkor kell dobni, ha a hamisítvány hitelességét valaki kétségbe vonhatja.',
|
||||
Tulajdonsag: [Tulajdonsag.Intelligencia],
|
||||
Osztalyok: [Osztaly.Tolvaj],
|
||||
},
|
||||
{
|
||||
Id: 'k_jelek_olvasasa',
|
||||
Name: 'Jelek Olvasása',
|
||||
Description: 'A képzettséggel a karakter el tud olvasni más nyelven írt írásokat és feliratokat.',
|
||||
Tulajdonsag: [Tulajdonsag.Intelligencia],
|
||||
Osztalyok: [Osztaly.Tolvaj, Osztaly.Varazslo, Osztaly.Illuzionista],
|
||||
},
|
||||
{
|
||||
Id: 'k_koncentracio',
|
||||
Name: 'Koncentráció',
|
||||
Description: 'Ez a képesség arra teszi alkalmassá a varázshasználót, hogy nehéz körülmények között – sebesülten, vágtató lovon, hánykolódó hajón, stb. – is alkalmazhassa varázslatait.',
|
||||
Tulajdonsag: [Tulajdonsag.Bolcsesseg],
|
||||
Osztalyok: [Osztaly.Varazslo, Osztaly.Illuzionista],
|
||||
},
|
||||
{
|
||||
Id: 'k_lovaglas',
|
||||
Name: 'Lovaglás',
|
||||
Description: 'A karakter kiemelkedően jól ért a lovagláshoz; harcban és nehéz helyzetekben is csodákra képes sarkallni hátasát.',
|
||||
Tulajdonsag: [Tulajdonsag.Ugyesseg],
|
||||
},
|
||||
{
|
||||
Id: 'k_maszas',
|
||||
Name: 'Mászás',
|
||||
Description: 'A képzettség olyan falakra való felmászásra alkalmas, ami egy átlagembernek komol gondot jelentene. Sikertelen próba esetén a karakter lezuhan, vagy a feladat meghaladja a képességeit.',
|
||||
Tulajdonsag: [Tulajdonsag.Ero],
|
||||
},
|
||||
{
|
||||
Id: 'k_megfigyeles',
|
||||
Name: 'Megfigyelés',
|
||||
Description: 'Ez a képzettség olyan érzékelési képességet jelent, ami meghaladja az átlagemberét. Így olyan részletek vehetők észre, amelye szabad szemmel láthatóak, de csak az avatott megfigyelő számára.',
|
||||
Tulajdonsag: [Tulajdonsag.Bolcsesseg],
|
||||
},
|
||||
{
|
||||
Id: 'k_meregkeveres',
|
||||
Name: 'Méregkeverés',
|
||||
Description: 'A megfelelő eszközök és alapanyagok birtokában különféle mérgek készíthetők. Sikertelen próbadobás esetén a keverék hatástalan, vagy a méregkeverő veszélybe sodorja önmagát.',
|
||||
Tulajdonsag: [Tulajdonsag.Intelligencia],
|
||||
Osztalyok: [Osztaly.Tolvaj],
|
||||
},
|
||||
{
|
||||
Id: 'k_mesterseg',
|
||||
Name: 'Mesterség',
|
||||
Description: 'A karakter járatos egy kiválasztott mesterségben – pl. kovácsolás, gyertyaöntés, adószedés, ötvösség. A kézügyességet igénylő mesterségekhez Ügyesség, a szellemi foglalkozásokhoz Intelligencia szükséges.',
|
||||
Tulajdonsag: [Tulajdonsag.Intelligencia, Tulajdonsag.Ugyesseg],
|
||||
},
|
||||
{
|
||||
Id: 'k_nyomkereses',
|
||||
Name: 'Nyomkeresés',
|
||||
Description: 'A karakter képes a nyomok követésére és hozzávetőleges azonosítására, vagyis megtudhatja, milyen régiek, miféle szerzet hagyta őket, milyen gyorsan haladt a nyomokat hagyó, stb.',
|
||||
Tulajdonsag: [Tulajdonsag.Bolcsesseg],
|
||||
},
|
||||
{
|
||||
Id: 'k_osonas',
|
||||
Name: 'Osonás',
|
||||
Description: 'Csöndes és általában viszonylag gyors mozgás.',
|
||||
Tulajdonsag: [Tulajdonsag.Ugyesseg],
|
||||
},
|
||||
{
|
||||
Id: 'k_rejtozes',
|
||||
Name: 'Rejtőzés',
|
||||
Description: 'A képzettséget ismerő karakter olyan helyeken is elrejtőzhet, ahol más nem volna képes – például sötétebb sarkokban, árnyékokban.',
|
||||
Tulajdonsag: [Tulajdonsag.Ugyesseg],
|
||||
},
|
||||
{
|
||||
Id: 'k_szabadulomuveszet',
|
||||
Name: 'Szabadulóművészet',
|
||||
Description: 'A karakter képes kiszabadulni kötelékeiből és láncaiból.',
|
||||
Tulajdonsag: [Tulajdonsag.Ugyesseg],
|
||||
Osztalyok: [Osztaly.Tolvaj],
|
||||
},
|
||||
{
|
||||
Id: 'k_tudas',
|
||||
Name: 'Tudás',
|
||||
Description: 'A karakter járatos egy bizonyos tudományterületen. Számos példa lehetséges, a leggyakoribbak a Történelemismeret, Országismeret, Mágiaismeret (csak varázshasználók sajátíthatják el), Teológia, Vadonismeret és a Növényismeret.',
|
||||
Tulajdonsag: [Tulajdonsag.Intelligencia],
|
||||
},
|
||||
{
|
||||
Id: 'k_ugras',
|
||||
Name: 'Ugrás',
|
||||
Description: 'A karakter képes átugrani szélesebb vagy magasabb akadályokat is, és tompíthatja az esésből származó sebesüléseket. Ha a próba sikertelen, a karakter leesik.',
|
||||
Tulajdonsag: [Tulajdonsag.Ero],
|
||||
},
|
||||
{
|
||||
Id: 'k_uszas',
|
||||
Name: 'Úszás',
|
||||
Description: 'A karakter jól tud úszni, akár nehéz körülmények között (zajló vízben, megterhelten, stb.) is képes a felszínen maradni.',
|
||||
Tulajdonsag: [Tulajdonsag.Ero],
|
||||
},
|
||||
{
|
||||
Id: 'k_varazslatismeret',
|
||||
Name: 'Varázslatismeret',
|
||||
Description: 'A Mágiaismerettel ellentétben ez a képzettség nem a mágia elméletében, hanem a konkrét varázslatokban való ismereteket méri. Sikeres próbával a karakter azonosíthatja az elmondás alatt álló varázslatokat (NF= a mentődobás nehézsége), bizonyos mágikus effektusokat, csapdákat, stb.',
|
||||
Tulajdonsag: [Tulajdonsag.Intelligencia],
|
||||
Osztalyok: [Osztaly.Illuzionista, Osztaly.Varazslo],
|
||||
},
|
||||
{
|
||||
Id: 'k_zarnyitas',
|
||||
Name: 'Zárnyitás',
|
||||
Description: 'Tolvajszerszámok segítségével a karakter felnyithatja a különféle mechanikus zárakat. Sikertelen próba esetén nem képes az adott zár felnyitására – egészen addig, amíg új tapasztalatokat nem szerez (vagyis a következő szintlépéséig).',
|
||||
Tulajdonsag: [Tulajdonsag.Ugyesseg],
|
||||
Osztalyok: [Osztaly.Tolvaj],
|
||||
},
|
||||
{
|
||||
Id: 'k_zsebmetszes',
|
||||
Name: 'Zsebmetszés',
|
||||
Description: 'Őrizetlenül hagyott vagy övön, zsebben található kisebb tárgyak észrevétlen eltulajdonítása. Ha a próba sikertelen, a karaktert észreveszik vagy legalábbis gyanút kelt.',
|
||||
Tulajdonsag: [Tulajdonsag.Ugyesseg],
|
||||
Osztalyok: [Osztaly.Tolvaj],
|
||||
},
|
||||
]
|
||||
|
||||
export const TolvajKepzettsegList = KepzettsegLista.filter(x => x.Osztalyok?.includes(Osztaly.Tolvaj))
|
||||
|
||||
export const Kepzettsegek: Record<KepzettsegId, Kepzettseg> =
|
||||
KepzettsegLista.reduce(
|
||||
(acc: Record<KepzettsegId, Kepzettseg>, k) => { acc[k.Id] = k; return acc; },
|
||||
{} as Record<KepzettsegId, Kepzettseg>);
|
||||
|
||||
export function AvailableKezpettsegList(osztaly: Osztaly): Kepzettseg[] {
|
||||
return KepzettsegLista.filter(k => k.Osztalyok == null || k.Osztalyok.includes(osztaly))
|
||||
}
|
||||
|
||||
export function GetNumberOfKepzettsegek(t_int: number, faj: Faj, max: number) {
|
||||
let numberOfKepzettseg = 3 + Modifier(t_int) + (faj === Faj.Ember ? 1 : 0)
|
||||
|
||||
if (numberOfKepzettseg < 1) {
|
||||
numberOfKepzettseg = 1
|
||||
console.log('Adjusted Number of Kepzetsegek = ', numberOfKepzettseg)
|
||||
}
|
||||
if (numberOfKepzettseg > max) {
|
||||
numberOfKepzettseg = max
|
||||
console.log('Adjusted Number of Kepzetsegek = ', numberOfKepzettseg)
|
||||
}
|
||||
return numberOfKepzettseg;
|
||||
}
|
||||
|
||||
export function SetDefaultTolvajKepzettsegek(karakter: Pick<KarakterInputs, 'osztaly' | 'tolvajKepzettsegek'>, changeTolvajKepzettsegek: (tolvajKepzettsegek?: KepzettsegId[]) => void) {
|
||||
if (karakter.osztaly !== Osztaly.Tolvaj && karakter.tolvajKepzettsegek != null) {
|
||||
changeTolvajKepzettsegek(undefined)
|
||||
}
|
||||
if (karakter.osztaly === Osztaly.Tolvaj && (karakter.tolvajKepzettsegek == null || karakter.tolvajKepzettsegek.length === 0)) {
|
||||
const tolvajKepzettsegek = TolvajKepzettsegList.slice(0, 4).map(x => x.Id)
|
||||
changeTolvajKepzettsegek(tolvajKepzettsegek)
|
||||
}
|
||||
}
|
||||
|
||||
export function GetKepzettsegListaN(karakter: Pick<KarakterInputs, 'osztaly' | 'faj' | 'kepzettsegek' | 'tolvajKepzettsegek'>) {
|
||||
const availableKepzettsegList = AvailableKezpettsegList(karakter.osztaly)
|
||||
return (n: number): Kepzettseg[] => {
|
||||
let available = [...availableKepzettsegList]
|
||||
if (n === 0) {
|
||||
if (karakter.faj === Faj.Eszaki) {
|
||||
return [Kepzettsegek.k_hajozas]
|
||||
}
|
||||
if (karakter.faj === Faj.Etuniai) {
|
||||
return [Kepzettsegek.k_lovaglas]
|
||||
}
|
||||
if (karakter.faj === Faj.Birodalmi && karakter.osztaly !== Osztaly.Tolvaj) {
|
||||
available = [Kepzettsegek.k_meregkeveres, Kepzettsegek.k_alkimia]
|
||||
}
|
||||
}
|
||||
const kepzettsegekWithoutN = [...karakter.kepzettsegek.slice(0, n), ...karakter.kepzettsegek.slice(n + 1)]
|
||||
return available.filter(x => !kepzettsegekWithoutN.includes(x.Id) && !karakter.tolvajKepzettsegek?.includes(x.Id))
|
||||
}
|
||||
}
|
||||
|
||||
export function SetDefaultKepzettsegek(karakter: Pick<KarakterInputs, 'osztaly' | 'faj' | 'tulajdonsagok' | 'kepzettsegek' | 'tolvajKepzettsegek'>, changeKepzettsegek: (k: KepzettsegId[]) => void) {
|
||||
const availableKepzettsegList = AvailableKezpettsegList(karakter.osztaly)
|
||||
const numberOfKepzettsegek = GetNumberOfKepzettsegek(karakter.tulajdonsagok.t_int, karakter.faj, availableKepzettsegList.length)
|
||||
let kepzettsegek = [...karakter.kepzettsegek]
|
||||
|
||||
let mustChangeKepzettsegek = false
|
||||
|
||||
const restrictedKepzettsegek = GetKepzettsegListaN(karakter)(0)
|
||||
if (kepzettsegek.length === 0) {
|
||||
if (restrictedKepzettsegek.length > 0) {
|
||||
kepzettsegek.push(restrictedKepzettsegek[0].Id)
|
||||
mustChangeKepzettsegek = true
|
||||
}
|
||||
} else {
|
||||
if (!restrictedKepzettsegek.includes(Kepzettsegek[kepzettsegek[0]])) {
|
||||
kepzettsegek[0] = restrictedKepzettsegek[0].Id
|
||||
mustChangeKepzettsegek = true
|
||||
}
|
||||
}
|
||||
|
||||
if (kepzettsegek.length < numberOfKepzettsegek) {
|
||||
for (let i = kepzettsegek.length; i < numberOfKepzettsegek; i++) {
|
||||
const kepzettsegLista = GetKepzettsegListaN({...karakter, kepzettsegek})(i)
|
||||
if (kepzettsegLista.length > 0) {
|
||||
kepzettsegek.push(kepzettsegLista[0].Id)
|
||||
}
|
||||
}
|
||||
mustChangeKepzettsegek = true
|
||||
}
|
||||
if (kepzettsegek.length > numberOfKepzettsegek){
|
||||
kepzettsegek = kepzettsegek.slice(0, numberOfKepzettsegek)
|
||||
mustChangeKepzettsegek = true
|
||||
}
|
||||
if (mustChangeKepzettsegek){
|
||||
changeKepzettsegek(kepzettsegek)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
export function dAny(sides: number) {
|
||||
return Math.floor(Math.random() * sides) + 1;
|
||||
}
|
||||
|
||||
export function d6() {
|
||||
return dAny(6)
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import {BaseHP} from "./masodlagos_ertekek";
|
||||
import {dAny} from "./kockak";
|
||||
import {TulajdonsagIDs, TulajdonsagokTotal} from "./tulajdonsag";
|
||||
import {KarakterInputs} from "./karakter";
|
||||
import {GetFajDetails} from "./faj";
|
||||
import {Osztaly} from "./osztaly";
|
||||
import fegyverek from "./fegyver.json"
|
||||
import {AllowedFegyver} from "./allowed-fegyver";
|
||||
|
||||
export function PickableSpecializationFilter(existingSpecilizations: string[], szint: number) {
|
||||
return (fegyver: {Id: string}) => existingSpecilizations.filter(x => x === fegyver.Id).length < (szint < 9 ? 1 : 2)
|
||||
}
|
||||
|
||||
export function LevelUp(karakter: KarakterInputs, changeKarakter: (input: KarakterInputs) => void) {
|
||||
const tulajdonsagokTotal = TulajdonsagokTotal(karakter)
|
||||
const szint = karakter.szint + 1
|
||||
const dice = BaseHP(karakter.osztaly)
|
||||
const roll = dAny(dice)
|
||||
const hpRolls = [...karakter.hpRolls, roll]
|
||||
console.log(`Level ${szint} HP roll on d${dice} is: ${roll}`)
|
||||
let tulajdonsagNovelesek = karakter.tulajdonsagNovelesek
|
||||
if (szint % 4 === 0) {
|
||||
for (const tulajdonsag of TulajdonsagIDs) {
|
||||
if (tulajdonsagokTotal[tulajdonsag] < 18) {
|
||||
tulajdonsagNovelesek = [...tulajdonsagNovelesek, tulajdonsag]
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let harcosSpecializaciok = karakter.harcosSpecializaciok
|
||||
if(karakter.osztaly === Osztaly.Harcos && szint % 2 === 1) {
|
||||
const nextPickableFegyverId = fegyverek.data.filter(PickableSpecializationFilter(karakter.harcosSpecializaciok, karakter.szint))[0].Id
|
||||
harcosSpecializaciok = [...harcosSpecializaciok, nextPickableFegyverId]
|
||||
}
|
||||
let kalozKritikus = karakter.kalozKritikus
|
||||
if(karakter.osztaly === Osztaly.Kaloz && szint % 3 === 0) {
|
||||
const nextPickableFegyverId = AllowedFegyver(Osztaly.Kaloz, []).filter(PickableSpecializationFilter(karakter.kalozKritikus, szint))[0].Id
|
||||
kalozKritikus = [...kalozKritikus, nextPickableFegyverId]
|
||||
}
|
||||
changeKarakter({...karakter, szint, hpRolls, tulajdonsagNovelesek, harcosSpecializaciok, kalozKritikus})
|
||||
}
|
||||
|
||||
export function LevelDown(karakter: KarakterInputs, changeKarakter: (input: KarakterInputs) => void) {
|
||||
let tulajdonsagNovelesek = karakter.tulajdonsagNovelesek
|
||||
if (karakter.szint % 4 === 0) {
|
||||
tulajdonsagNovelesek = tulajdonsagNovelesek.slice(0, -1)
|
||||
}
|
||||
const szint = karakter.szint - 1
|
||||
const hpRolls = karakter.hpRolls.slice(0, -1)
|
||||
let harcosSpecializaciok = karakter.harcosSpecializaciok
|
||||
if (karakter.osztaly === Osztaly.Harcos && szint % 2 === 0) {
|
||||
harcosSpecializaciok = harcosSpecializaciok.slice(0, -1)
|
||||
}
|
||||
changeKarakter({...karakter, szint, hpRolls, tulajdonsagNovelesek, harcosSpecializaciok})
|
||||
}
|
||||
|
||||
export function CanLevelUp(karakter: Pick<KarakterInputs, 'szint' | 'faj' | 'osztaly'>): boolean {
|
||||
return karakter.szint < 10 && karakter.szint < GetFajDetails(karakter.faj).Szintkorlatok[karakter.osztaly]
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import {Mentok, MentokTotal} from "./mentok";
|
||||
import {Osztaly} from "./osztaly";
|
||||
import {KarakterInputs} from "./karakter";
|
||||
import {Modifier} from "./tulajdonsag";
|
||||
import {CelzoTB, KozelharciTB} from "./tamadas_bonusz";
|
||||
import {Faj} from "./faj";
|
||||
import { GetPajzs, GetPancel, MaxAbilityVO } from "./felszereles";
|
||||
|
||||
export interface MasodlagosErtekekView {
|
||||
HP: number
|
||||
VO: number
|
||||
KozelharciTB: number[]
|
||||
CelzoTB: number[]
|
||||
Mentok: Mentok
|
||||
}
|
||||
|
||||
export type KarakterpickForMasodlagosErtekek = Pick<KarakterInputs, 'osztaly' | 'hpRolls' | 'tulajdonsagok' | 'szint' | 'faj' | 'felszereles'>
|
||||
|
||||
export function BaseHP(osztaly: Osztaly) {
|
||||
let base = 4;
|
||||
switch (osztaly){
|
||||
case Osztaly.Barbar:
|
||||
base = 12
|
||||
break;
|
||||
case Osztaly.Amazon:
|
||||
case Osztaly.Ijasz:
|
||||
case Osztaly.Kaloz:
|
||||
case Osztaly.Harcos:
|
||||
base = 10;
|
||||
break
|
||||
case Osztaly.Pap:
|
||||
base = 8;
|
||||
break;
|
||||
case Osztaly.Tolvaj:
|
||||
base = 6;
|
||||
break;
|
||||
case Osztaly.Varazslo:
|
||||
case Osztaly.Illuzionista:
|
||||
base = 4;
|
||||
break;
|
||||
}
|
||||
return base
|
||||
}
|
||||
|
||||
export function HP(karakter: Pick<KarakterInputs, 'osztaly' | 'tulajdonsagok' | 'hpRolls'>): number {
|
||||
const egeszsegModifier = Modifier(karakter.tulajdonsagok.t_egs)
|
||||
return BaseHP(karakter.osztaly) + egeszsegModifier + karakter.hpRolls
|
||||
// https://lfg.hu/forum/topic/15079-kard-es-magia/page/219/#comment-2218333
|
||||
.map(hp => Math.max(1, hp + egeszsegModifier))
|
||||
.reduce((sum, val) => sum + val, 0)
|
||||
}
|
||||
|
||||
export function VO(karakter: Pick<KarakterInputs, 'tulajdonsagok' | 'faj' | 'osztaly' | 'szint' | 'felszereles'>): number {
|
||||
const pancel = GetPancel(karakter.felszereles.pancelID)
|
||||
const pancelVO = pancel?.VO ?? 0
|
||||
const pajzsVO = GetPajzs(karakter.felszereles.pajzsID)?.VO ?? 0
|
||||
let vo = 10 + pajzsVO + pancelVO
|
||||
let abilityVO = Modifier(karakter.tulajdonsagok.t_ugy)
|
||||
if (karakter.osztaly === Osztaly.Kaloz) {
|
||||
vo += Math.floor(karakter.szint / 3)
|
||||
}
|
||||
if (karakter.osztaly === Osztaly.Amazon) {
|
||||
if (karakter.tulajdonsagok.t_kar > karakter.tulajdonsagok.t_ugy) {
|
||||
abilityVO = Modifier(karakter.tulajdonsagok.t_kar)
|
||||
}
|
||||
vo += Math.floor(karakter.szint / 2)
|
||||
}
|
||||
if (karakter.faj === Faj.Felszerzet){
|
||||
vo += 1
|
||||
}
|
||||
if (pancel) {
|
||||
abilityVO = Math.min(MaxAbilityVO(pancel.Type), abilityVO)
|
||||
}
|
||||
vo += abilityVO
|
||||
|
||||
return vo
|
||||
}
|
||||
|
||||
export function CalculateMasodlagosErtekek(karakter: KarakterpickForMasodlagosErtekek): MasodlagosErtekekView {
|
||||
return {
|
||||
HP: HP(karakter),
|
||||
VO: VO(karakter),
|
||||
CelzoTB: CelzoTB(karakter),
|
||||
KozelharciTB: KozelharciTB(karakter),
|
||||
Mentok: MentokTotal(karakter)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"varazslatok": [
|
||||
[3,1],
|
||||
[4,2],
|
||||
[4,2,1],
|
||||
[5,3,2],
|
||||
[5,3,2,1],
|
||||
[5,3,2,2],
|
||||
[6,4,3,2,1],
|
||||
[6,4,3,3,2],
|
||||
[6,4,4,3,2,1],
|
||||
[6,4,4,3,3,2],
|
||||
[7,5,4,4,3,2],
|
||||
[7,5,4,4,3,3],
|
||||
[7,5,5,4,4,3],
|
||||
[7,5,5,4,4,3],
|
||||
[7,5,5,5,4,4],
|
||||
[8,6,5,5,4,4],
|
||||
[8,6,5,5,5,4],
|
||||
[8,6,6,5,5,4],
|
||||
[8,6,6,5,5,5],
|
||||
[8,6,6,6,5,5]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import MemorizaltVarazslatTabla from "./memorizalt_varazslat_tabla.json";
|
||||
import {KarakterInputs} from "./karakter";
|
||||
import {Osztaly} from "./osztaly";
|
||||
import {Modifier} from "./tulajdonsag";
|
||||
|
||||
function isSpellcaster(osztaly: Osztaly): boolean {
|
||||
return osztaly === Osztaly.Pap || osztaly === Osztaly.Illuzionista || osztaly === Osztaly.Varazslo;
|
||||
}
|
||||
|
||||
function getMagicAbilityModifier(karakter: Pick<KarakterInputs, 'osztaly' | 'tulajdonsagok'>) : number {
|
||||
const magicAbility = karakter.osztaly === Osztaly.Pap ? karakter.tulajdonsagok.t_bol : karakter.tulajdonsagok.t_int
|
||||
return Modifier(magicAbility)
|
||||
}
|
||||
|
||||
export function NapiVarazslatok(karakter: Pick<KarakterInputs, 'szint' | 'osztaly' | 'tulajdonsagok'>) : number[] {
|
||||
if (!isSpellcaster(karakter.osztaly)) {
|
||||
return []
|
||||
}
|
||||
const magicAbilityModifier = getMagicAbilityModifier(karakter)
|
||||
const response = [...MemorizaltVarazslatTabla.varazslatok[karakter.szint-1]]
|
||||
for (let i = 1; i <= magicAbilityModifier && i < response.length; i++){
|
||||
response[i] += 1
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
export function CalculateVarazslatMentokNF(karakter: Pick<KarakterInputs, 'osztaly' | 'tulajdonsagok'>): number[] {
|
||||
if (!isSpellcaster(karakter.osztaly)) {
|
||||
return []
|
||||
}
|
||||
const magicAbilityModifier = getMagicAbilityModifier(karakter)
|
||||
const response = []
|
||||
for (let spellLevel = 0; spellLevel < 6; spellLevel++){
|
||||
const NF = 10 + spellLevel + magicAbilityModifier
|
||||
response.push(NF)
|
||||
}
|
||||
return response
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import {Osztaly} from "./osztaly";
|
||||
import {KarakterTulajdonsagok, TulajdonsagModosito} from "./tulajdonsag";
|
||||
import {KarakterInputs} from "./karakter";
|
||||
|
||||
export interface Mentok {
|
||||
kitartas: number
|
||||
reflex: number
|
||||
akaratero: number
|
||||
}
|
||||
export type MentoTipus = keyof Mentok
|
||||
|
||||
export function MentoTipusLabel(tipus: MentoTipus): string {
|
||||
switch (tipus) {
|
||||
case "akaratero":
|
||||
return "Akaraterő";
|
||||
case "kitartas":
|
||||
return "Kitartás";
|
||||
case "reflex":
|
||||
return "Reflex";
|
||||
}
|
||||
}
|
||||
|
||||
export function ElsodlegesMento(szint: number): number {
|
||||
return Math.min(Math.floor(2 + szint / 2), 10);
|
||||
}
|
||||
|
||||
export function MasodlagosMento(szint: number): number {
|
||||
return Math.floor(szint / 3)
|
||||
}
|
||||
|
||||
export function ElsodlegesMentok(osztaly: Osztaly) : MentoTipus[] {
|
||||
let t: MentoTipus[] = []
|
||||
switch (osztaly){
|
||||
case Osztaly.Barbar:
|
||||
case Osztaly.Amazon:
|
||||
case Osztaly.Ijasz:
|
||||
case Osztaly.Kaloz:
|
||||
case Osztaly.Harcos:
|
||||
t = ['kitartas'];
|
||||
break;
|
||||
case Osztaly.Pap:
|
||||
t = ['kitartas', 'akaratero'];
|
||||
break;
|
||||
case Osztaly.Tolvaj:
|
||||
t = ['reflex'];
|
||||
break;
|
||||
case Osztaly.Varazslo:
|
||||
case Osztaly.Illuzionista:
|
||||
t = ['akaratero']
|
||||
break;
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
export function MentokAlap(osztaly: Osztaly, szint: number = 1) {
|
||||
const elsodlegesek = ElsodlegesMentok(osztaly)
|
||||
return {
|
||||
kitartas: elsodlegesek.includes('kitartas') ? ElsodlegesMento(szint) : MasodlagosMento(szint),
|
||||
reflex: elsodlegesek.includes('reflex') ? ElsodlegesMento(szint) : MasodlagosMento(szint),
|
||||
akaratero: elsodlegesek.includes('akaratero') ? ElsodlegesMento(szint) : MasodlagosMento(szint),
|
||||
}
|
||||
}
|
||||
|
||||
export function MentoModositok(tulajdonsagModositok: KarakterTulajdonsagok) {
|
||||
return {
|
||||
kitartas: tulajdonsagModositok.t_egs,
|
||||
reflex: tulajdonsagModositok.t_ugy,
|
||||
akaratero: tulajdonsagModositok.t_bol,
|
||||
}
|
||||
}
|
||||
|
||||
export function MentokTotal(karakter: Pick<KarakterInputs, 'osztaly' | 'szint' | 'tulajdonsagok'>) {
|
||||
const alap = MentokAlap(karakter.osztaly, karakter.szint)
|
||||
const modositok = MentoModositok(TulajdonsagModosito(karakter.tulajdonsagok))
|
||||
return {
|
||||
kitartas: alap.kitartas + modositok.kitartas,
|
||||
reflex: alap.reflex + modositok.reflex,
|
||||
akaratero: alap.akaratero + modositok.akaratero,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
import {GetPancel, KarakterFelszereles} from "./felszereles";
|
||||
import {AllowedPancelTypes} from "./allowed-pancel-types";
|
||||
|
||||
export enum Osztaly {
|
||||
Harcos = 'o_harcos',
|
||||
Ijasz = 'o_ijasz',
|
||||
Amazon = 'o_amazon',
|
||||
Kaloz = 'o_kaloz',
|
||||
Barbar = 'o_barbar',
|
||||
Pap = 'o_pap',
|
||||
Tolvaj = 'o_tolvaj',
|
||||
Varazslo = 'o_varazslo',
|
||||
Illuzionista = 'o_illuzionista',
|
||||
}
|
||||
|
||||
export function SetFelszerelesForChangedOsztaly(o: Osztaly, felszereles: KarakterFelszereles, changeFelszereles: (f: KarakterFelszereles) => void) {
|
||||
const allowedPancelTypes = AllowedPancelTypes([o])
|
||||
const pancel = GetPancel(felszereles.pancelID)
|
||||
if (pancel && !allowedPancelTypes.includes(pancel.Type)) {
|
||||
changeFelszereles({...felszereles, pancelID: undefined})
|
||||
}
|
||||
if (allowedPancelTypes.length === 0 && !!felszereles.pajzsID){
|
||||
changeFelszereles({...felszereles, pajzsID: undefined})
|
||||
}
|
||||
}
|
||||
|
||||
export function OsztalyLabel(osztaly: Osztaly) : string {
|
||||
switch (osztaly) {
|
||||
case Osztaly.Amazon: return 'Amazon';
|
||||
case Osztaly.Barbar: return 'Barbár';
|
||||
case Osztaly.Pap: return 'Pap';
|
||||
case Osztaly.Illuzionista: return 'Illúzionista';
|
||||
case Osztaly.Varazslo: return 'Varázsló';
|
||||
case Osztaly.Harcos: return 'Harcos';
|
||||
case Osztaly.Ijasz: return 'Íjász';
|
||||
case Osztaly.Kaloz: return 'Tengerész/Kalóz';
|
||||
case Osztaly.Tolvaj: return 'Tolvaj'
|
||||
}
|
||||
}
|
||||
|
||||
export function OsztalyDescription(osztaly: Osztaly) : string {
|
||||
switch (osztaly) {
|
||||
case Osztaly.Harcos:
|
||||
case Osztaly.Amazon:
|
||||
case Osztaly.Barbar:
|
||||
case Osztaly.Ijasz:
|
||||
case Osztaly.Kaloz:
|
||||
return 'A harcosok a fegyverhasználat mesterei. Megállják a helyüket a közelharcban és a távolsági összecsapásokban is, s sokkal jobban viselik a sebesüléseket, mint más osztályok képviselői. Ez az osztály mind közül a leggyakoribb, de egyben a legváltozatosabb is – öt alosztállyal rendelkezik.';
|
||||
case Osztaly.Tolvaj:
|
||||
return 'A tolvajok a becstelen harc és a csöndes gyilkolás mesterei (közülük sokan alkalmaznak mérgeket – őket orgyilkosoknak nevezik). Harci képességeik és életerejük viszonylag gyenge, s nehezebb vértezeteket sem használhatnak. Ezért ha módjukban áll, nem szemtől szembe, hanem lesből támadnak áldozataikra, és ha ez nem sikerülne, gyorsan kereket oldanak. Emellett alvilági pályafutásuk során számos hasznos képzettségben válnak járatossá.';
|
||||
case Osztaly.Pap:
|
||||
return 'A papok az istenek militáns varázshasználó szolgái. Hitük parancsait minden körülmények között be kell tartaniuk, s bizonyos rendszerességgel áldozatokat kell bemutatniuk. A papok csak istenükkel azonos vagy attól legfeljebb eggyel különböző jelleműek lehetnek. A papok csak az istenük által kijelölt fegyvereket forgathatják, de szabadon válogathatnak a különféle vértek között.';
|
||||
case Osztaly.Varazslo:
|
||||
return 'A varázslók kiemelkedő szellemi fegyelmezettségük segítségével képesek a magasabb fokú mágikus erőket irányító varázsigék memorizálására és fölhasználására. Tudásukat varázskönyekben rögzítik, s mindent elkövetnek egy ismeretlen formula megszerzéséért. Többségüket a magabiztos önhittség és az alacsonyabb szellemi képeségűek megvetése jellemzi. A varázslók nem képesek _bármiféle_ páncélban varázsolni, és csak kevés fegyvertípus forgatásában járatosak.';
|
||||
case Osztaly.Illuzionista:
|
||||
return 'A varázslók kiemelkedő szellemi fegyelmezettségük segítségével képesek a magasabb fokú mágikus erőket irányító varázsigék memorizálására és fölhasználására. Tudásukat varázskönyekben rögzítik, s mindent elkövetnek egy ismeretlen formula megszerzéséért. Többségüket a magabiztos önhittség és az alacsonyabb szellemi képeségűek megvetése jellemzi. Az illuzionisták a mágia egy igen hasonló, de több lényeges területen eltérő fajtáját művelik. Lételemük a káprázat, a megtévesztés és mások elméjének befolyásolása – többségük hipnotizőr vagy ügyes manipulátor. Az illuzionista varázslatok csekélyebb pusztító erőt képviselnek, ellenben egy élelmes illuzionista kezében szinte bármire képesek – beleértve a közönséges varázslók egyes varázslatainak utánzását. Az illuzionisták nem képesek _bármiféle_ páncélban varázsolni, és csak kevés fegyvertípus forgatásában járatosak.';
|
||||
}
|
||||
}
|
||||
|
||||
export function OsztalyProperties(osztaly: Osztaly) : string[] {
|
||||
switch (osztaly) {
|
||||
case Osztaly.Harcos: return [
|
||||
'Támadásbónusz: Szint * 1',
|
||||
'Mentődobások: Kitartás az első, Reflex és Akaraterő a második oszlop szerint',
|
||||
'Fegyverhasználat: az egzotikus fegyvereken kívül bármilyen fegyvertípust használhatnak',
|
||||
'Páncélhasználat: bármilyen',
|
||||
'Hp: szintenként 1d10, 9. szint („Nagyúr”) fölött 3/szint',
|
||||
'Képzettségek: 3',
|
||||
]
|
||||
case Osztaly.Ijasz: return [
|
||||
'Támadásbónusz: Szint x 1',
|
||||
'Mentődobások: Kitartás az első, Reflex és Akaraterő a második oszlop szerint',
|
||||
'Fegyverhasználat: az egzotikus fegyvereken kívül bármilyen fegyvertípust használhatnak',
|
||||
'Páncélhasználat: nehéz vérteken kívül bármilyen',
|
||||
'Hp: szintenként 1d10, 9. szint („Nagyúr”) fölött 3/szint',
|
||||
'Képzettségek: 3',
|
||||
]
|
||||
case Osztaly.Amazon: return [
|
||||
'Támadásbónusz: Szint x 1',
|
||||
'Mentődobások: Kitartás az első, Reflex és Akaraterő a második oszlop szerint',
|
||||
'Fegyverhasználat: az egzotikus fegyvereken kívül bármilyen fegyvertípust használhatnak',
|
||||
'Páncélhasználat: láncing vagy könnyebb vértek',
|
||||
'Hp: szintenként 1d10, 9. szint („Nagyúr”) fölött 3/szint',
|
||||
'Képzettségek: 3',
|
||||
]
|
||||
case Osztaly.Kaloz: return [
|
||||
'Támadásbónusz: Szint x 1',
|
||||
'Mentődobások: Kitartás az első, Reflex és Akaraterő a második oszlop szerint',
|
||||
'Fegyverhasználat: az egzotikus fegyvereken kívül bármilyen fegyvertípust használhatnak',
|
||||
'Páncélhasználat: nehéz vérteken kívül bármilyen',
|
||||
'Hp: szintenként 1d10, 9. szint („Nagyúr”) fölött 3/szint',
|
||||
'Képzettségek: 3',
|
||||
]
|
||||
case Osztaly.Barbar: return [
|
||||
'Támadásbónusz: Szint x 1',
|
||||
'Mentődobások: Kitartás az első, Reflex és Akaraterő a második oszlop szerint',
|
||||
'Fegyverhasználat: az egzotikus fegyvereken kívül bármilyen fegyvertípust használhatnak',
|
||||
'Páncélhasználat: bármilyen',
|
||||
'Hp: szintenként 1d12, 9. szint („Nagyúr”) fölött 3/szint',
|
||||
'Képzettségek: 3',
|
||||
]
|
||||
case Osztaly.Pap: return [
|
||||
'Támadásbónusz: Szint x 2/3',
|
||||
'Mentődobás: Kitartás és Akaraterő az első, Reflex a második oszlop szerint',
|
||||
'Fegyverhasználat: csak buzogányokat, tőröket és istenük kijelölt fegyvereit használhatják',
|
||||
'Páncélhasználat: bármilyen',
|
||||
'Hp: szintenként 1d8, 9. szint („Főpap”) fölött 2/szint',
|
||||
'Képzettségek: 3',
|
||||
]
|
||||
case Osztaly.Tolvaj: return [
|
||||
'Támadásbónusz: Szint x 2/3',
|
||||
'Mentődobás: Reflex az első, Kitartás és Akaraterő a második oszlop szerint',
|
||||
'Fegyverhasználat: tőröket, dobótűket, parittyákat, számszeríjakat , rövidíjakat és egykezes kardokat használhatnak',
|
||||
'Páncélhasználat: csak könnyű',
|
||||
'Hp: szintenként 1d6, 9. szint („Mestertolvaj”) fölött 2/szint',
|
||||
'Képzettségek: 7 (ebből legalább 4 minden képpen a „tolvajképzettségek” listájáról); 9. és ezután minden páratlan szinten újabb, eddig akár tiltott képzettséget tanulhatnak meg.'
|
||||
]
|
||||
case Osztaly.Varazslo:
|
||||
case Osztaly.Illuzionista: return [
|
||||
'Támadásbónusz: Szint x 1/2',
|
||||
'Mentődobás: Akaraterő az első, Kitartás és Reflex a második oszlop szerint',
|
||||
'Fegyverhasználat: tőrt, botot, dobótűket, bunkót és parittyát használhatnak',
|
||||
'Páncélhasználat: nincs',
|
||||
'Hp: szintenként 1d4, 9. szint („Varázslónagyúr”) fölött 1/szint',
|
||||
'Képzettségek: 3'
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export interface Skill {
|
||||
Id: string
|
||||
Name: string,
|
||||
Description: string
|
||||
ExtendedDescription?: string[]
|
||||
}
|
||||
|
||||
export function OsztalySpecialSkills(osztaly: Osztaly) : Skill[] {
|
||||
switch (osztaly) {
|
||||
case Osztaly.Harcos: return [{
|
||||
Id: 's_harcos_harcos',
|
||||
Name: 'Harcos',
|
||||
Description: 'Speciális harci tapasztalatuknak köszönhetően minden páratlan szinten +2-t kapnak egy választott fegyvertípus (pl. csatabárd, hosszúkard, stb.) sebzésére. Ez fegyverenként csak egyszer választható, s arra is fölhasználható, hogy a harcos megtanulja egy egzotikus fegyver használatát, amire később specializálódhat is. 9. szinttől elérhető számukra a kettős specializáció: ezzel sebzésmódosítójukat az adott fegyverre +4-re emelhetik.'
|
||||
}
|
||||
]
|
||||
case Osztaly.Ijasz: return [
|
||||
{
|
||||
Id: 's_harcos_ijasz',
|
||||
Name: 'Íjász',
|
||||
Description: 'A távolsági harc mesterei. Íjak használatakor körönként eggyel többször támadhatnak. Értenek a visszacsapó íjak használatához is.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_ijasz_vert',
|
||||
Name: 'Kötelező mozgékonyság',
|
||||
Description: 'Az íjászok nem viselhetnek nehéz vérteket.'
|
||||
}
|
||||
]
|
||||
case Osztaly.Amazon: return [
|
||||
{
|
||||
Id: 's_harcos_amazon',
|
||||
Name: 'Amazon',
|
||||
Description: 'Az amazonok barbár népe szépségéről és a karizmatikus jelenlétre építő védekező harcmodoráról ismert.',
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_amazon_vert',
|
||||
Name: 'MMO vért',
|
||||
Description: 'Az amazonok csak láncinget vagy könnyebb vérteket viselhetnek, de VO-juk Szint/2-vel javul, továbbá Karizma- és Ügyességmódosítói közül a kedvezőbbet választhatják.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_amazon_csapatmunka',
|
||||
Name: 'Csapatmunka',
|
||||
Description: 'Ha kettő vagy több amazon együttesen harcol, VO-juk további 2 ponttal nő pszionikus képességeik miatt.'
|
||||
},
|
||||
]
|
||||
case Osztaly.Kaloz: return [
|
||||
{
|
||||
Id: 's_harcos_kaloz',
|
||||
Name: 'Tengerész/Kalóz',
|
||||
Description: 'A tengerészek a hajózás mesterei; kereskedők, tengeri rablók és rabszolgavadászok.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_kaloz_ugyes_huzas',
|
||||
Name: 'Ügyes húzás',
|
||||
Description: 'A kalózok és tengerészek ha magasabb, Ügyességbónuszukat adják hozzá közelharci támadásaikhoz.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_kaloz_vasmacska',
|
||||
Name: 'Vasmacska',
|
||||
Description: 'A kalózok és tengerészek nem viselhetnek nehéz vértezetet, de VO-juk könnyű vértben Szint/3-al javul.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_kaloz_kritikus',
|
||||
Name: 'Kritikus',
|
||||
Description: 'Minden harmadik szinten kiválaszthatnak egy fegyvert, amivel könnyebben okoznak kritikus sebesülést, tehát pl. csatabárddal 20 helyett 19-20-on, hosszúkarddal 19-20 helyett 18-20-on, szablyával 18-20 helyett 17-20-on, stb. Ez a képesség 9. szintig fegyverenként csak egyszer választható.'
|
||||
}]
|
||||
case Osztaly.Barbar: return [
|
||||
{
|
||||
Id: 's_harcos_barbar',
|
||||
Name: 'Barbár',
|
||||
Description: 'A barbár törzsek köré sorolhatók a pusztai és sivatagi nomádok, a déli dzsungelek emberevői és az északi tengermelléki rablók nemzetségei egyaránt.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_barbar_eletero',
|
||||
Name: 'Túlélő',
|
||||
Description: 'A barbárok 1d12-vel dobják a Hp-jüket, -5 Hp-ig öntudatuknál vannak és +1 bónuszt (10. szinttől +2, 15. szinttől +4) kapnak a mentődobásaikra.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_barbar_iras',
|
||||
Name: 'Írástudatlan',
|
||||
Description: 'Minden barbár írástudatlanul kezdi a játékot, de ha kell, később megtanulhatja a betűvetést.'
|
||||
}
|
||||
]
|
||||
case Osztaly.Pap: return [
|
||||
{
|
||||
Id: 's_pap_varazslat',
|
||||
Name: 'Varázslatok',
|
||||
Description: 'a papi varázslatok általában gyógyításra, mások megsegítésére és vallási feladatok ellátására szolgálnak. Minél magasabb szintűek, egy nap annál több varázslatot tudnak alkalmazni a következő oldalon található táblának megfelelően. Például egy 4. szintű, 17-es Bölcsességgel rendelkező pap öt nulladik szintű, négy első szintű és három második szintű varázslatot tarthat naponta elméjében.'
|
||||
},
|
||||
{
|
||||
Id: 's_pap_gyogyseb',
|
||||
Name: 'Gyógyítás vagy sebokozás',
|
||||
Description: 'a pap az aznap már memorizált (megtanult) varázslatokat gyógyításra vagy sebek okozására is fölhasználhatja. Érintésével a varázslat minden szintjéért 1d8 Hp-t gyógyít vagy sebez – így pl. egy Ómen elhasználásával 2d8 Hp-t. Az így konvertált varázslat természetesen elvész. Az, hogy a képesség sebek gyógyítására vagy okozására szolgál, a pap istenétől függ. A békésebb istenek főleg az elsőt, a harciasabbak főleg a másodikat részesítik előnyben, s vannak olyanok is, akik híveikre bízzák, hogy melyik utat választják. Ha azonban a pap már eldöntötte, melyik képességben járatos, döntését többé nem másíthatja meg!'
|
||||
},
|
||||
{
|
||||
Id: 's_pap_elohalott',
|
||||
Name: 'Élőholtak elűzése vagy irányítása',
|
||||
Description: 'A papok istenük dogmájának megfelelően képesek lehetnek arra, hogy élőholt szörnyeket (mint például zombikat, lidérceket vagy vámpírokat) szimbólumuk felmutatásával elűzzenek vagy szolgálatukba állítsanak. Ez a képesség naponta csak egyszer (5. szinttől kétszer, 10. szinttől háromszor, 15. szinttől négyszer) használható. A cselekedet a következőképpen működik:',
|
||||
ExtendedDescription: [
|
||||
'A pap [1d20+Kar bónusz] próbát tesz. Ennek az értékét összeveti a standard bónusztáblázattal. Az innen kiolvasható módosítót hozzáadja saját szintjéhez (ha negatív, akkor levonja). Az eredmény jelzi, hogy a pap legfeljebb milyen szintű élőholtakra lesz hatással. Ha tehát pl. a próba végeredménye 14 és a pap ötödik szintű, akkor 5+1, azaz 6. szintű a legerősebb élőhalott, amire a kísérlet sikeres. A 20-as dobás itt is automatikus siker, az 1-es automatikus kudarc.',
|
||||
'A pap [2d6+szint] szintű élőhalottat űzhet el vagy irányíthat. Először a leggyengébb élőholtakra hat, azután a következő leggyengébbekre, stb. Az elűzött élőholtak elmenekülnek a pap szeme elől és addig nem is ártanak neki és társainak, amíg a pap csapata meg nem támadja őket! Ezzel szemben a gonosz papok parancsokat adhatnak az irányított szörnyeknek. Mindkét hatás legfeljebb pár óráig tart, az élőholtak szintjétől és a körülményektől függően.',
|
||||
'Ha az összes szem előtt lévő élőholtat sikerült elűzni vagy irányítani és még maradt „a szent energiából”, akkor ismét el kell kezdeni a hatást a leggyengébb ellenségektől. Az így elűzött szörnyek megsemmisülnek, illetve irányítás esetén végleg a gonosz pap szolgálatába állnak.',
|
||||
'A két hatás egymás ellen is fölhasználható, például egy jó pap kiolthatja egy gonosz pap irányítását, de akár két gonosz pap is versenyezhet egy csapat sírlidérc „megtérítésén”.',
|
||||
]
|
||||
},
|
||||
{
|
||||
Id: 's_pap_invokacio',
|
||||
Name: 'Invokáció',
|
||||
Description: 'A pap kérheti istene segítségét (általában nevének kimondásával), ami +1-et, ritkábban +2-t ad hozzá dobásaihoz. A papok hetente annyiszor használhatják az invokációt, amekkora a Bölcsességbónuszuk (de legalább egyszer).'
|
||||
}
|
||||
]
|
||||
case Osztaly.Tolvaj: return [
|
||||
{
|
||||
Id: 's_tolvaj_orvtamadas',
|
||||
Name: 'Orvtámadás',
|
||||
Description: 'az orvtámadás akkor használható, ha a tolvaj meglepi áldozatát, tehát pl. csöndesen a hátába kerül, vagy beszélgetés közben tőrt ránt és egyetlen mozdulattal gyomron szúrja. Az orvtámadás minden páratlan szintért 1d6 bónusz sebzést okoz (maximuma +5d6). Dobó- és lőfegyverrel is használható, és ha a tolvaj úgy dönt, illetve a használt fegyver lehetővé teszi, az ellenfél elkábítására is alkalmazható.'
|
||||
},
|
||||
{
|
||||
Id: 's_tolvaj_kezdemenyezes',
|
||||
Name: 'Jobb kezdeményezés',
|
||||
Description: 'a tolvajok +4-et kapnak kezdeményezési dobásaikra.',
|
||||
},
|
||||
{
|
||||
Id: 's_tolvaj_kepzettsegek',
|
||||
Name: 'Tolvajképzettségek',
|
||||
Description: 'minden tolvaj jártas több olyan képzettségben, amely segíti a rejtőzködésben, a jól őrzött értékek eltulajdonításában és hasonló feladatokban. A tolvajok azokat a tolvajképzettségeket is használhatják, amelyekben nem járatosak külön, de ekkor szintjük nem számít bele a próbadobás módosítójába! A tolvajképzettségek listája: Álcázás, Csapdák állítása és eltávolítása, Egyensúlyozás, Értékbecslés, Hallgatózás, Hamisítás, Jelek olvasása, Keresés, Mászás, Megfigyelés, Méregkeverés, Osonás, Rejtőzés, Szabadulóművészet, Zárnyitás és Zsebmetszés.',
|
||||
},
|
||||
]
|
||||
case Osztaly.Varazslo: return [{
|
||||
Id: 's_varazslo_varazskonyv',
|
||||
Name: 'Varázskönyv',
|
||||
Description: 'egy első szintű varázsló varázskönyve 6 nulladik és 3 első szintű varázslatot tartalmaz, harmadik szintű kezdő karakteré ezen felül még 2 első szintűt és 2 második szintűt. Az újabb varázslatokat mások könyveiből, mágikus tekercsekből vagy más módszerek segítségével kell könyvébe másolnia. Az illuzionisták szintén varázskönyveket használnak, de eltérő mágiaformájuk miatt nem képesek a varázslói varázslatok megértésére – és viszont.'
|
||||
}]
|
||||
case Osztaly.Illuzionista: return [{
|
||||
Id: 's_illuzionista_varazskonyv',
|
||||
Name: 'Varázskönyv',
|
||||
Description: 'egy első szintű varázsló varázskönyve 6 nulladik és 3 első szintű varázslatot tartalmaz, harmadik szintű kezdő karakteré ezen felül még 2 első szintűt és 2 második szintűt. Az újabb varázslatokat mások könyveiből, mágikus tekercsekből vagy más módszerek segítségével kell könyvébe másolnia. Az illuzionisták szintén varázskönyveket használnak, de eltérő mágiaformájuk miatt nem képesek a varázslói varázslatok megértésére – és viszont.'
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"pajzs": [
|
||||
{
|
||||
"Id": "kis_fa",
|
||||
"Name": "Kis fapajzs ",
|
||||
"Type": "pajzs",
|
||||
"VO": 1,
|
||||
"Price": 3
|
||||
},
|
||||
{
|
||||
"Id": "kis_fem",
|
||||
"Name": "Kis fémpajzs ",
|
||||
"Type": "pajzs",
|
||||
"VO": 1,
|
||||
"Price": 9
|
||||
},
|
||||
{
|
||||
"Id": "nagy_fa",
|
||||
"Name": "Nagy fapajzs ",
|
||||
"Type": "pajzs",
|
||||
"VO": 2,
|
||||
"Price": 7
|
||||
},
|
||||
{
|
||||
"Id": "nagy_fem",
|
||||
"Name": "Nagy fémpajzs ",
|
||||
"Type": "pajzs",
|
||||
"VO": 2,
|
||||
"Price": 20
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"pancel": [
|
||||
{
|
||||
"Id": "tomott",
|
||||
"Name": "Tömött páncél",
|
||||
"Type": "konnyu",
|
||||
"VO": 1,
|
||||
"Price": 4
|
||||
},
|
||||
{
|
||||
"Id": "bor",
|
||||
"Name": "Bőrvért",
|
||||
"Type": "konnyu",
|
||||
"VO": 2,
|
||||
"Price": 5
|
||||
},
|
||||
{
|
||||
"Id": "kivert_bor",
|
||||
"Name": "Kivert bőrvért",
|
||||
"Type": "konnyu",
|
||||
"VO": 3,
|
||||
"Price": 15
|
||||
},
|
||||
{
|
||||
"Id": "gyuruvert",
|
||||
"Name": "Gyűrűvért",
|
||||
"Type": "konnyu",
|
||||
"VO": 3,
|
||||
"Price": 20
|
||||
},
|
||||
{
|
||||
"Id": "lancing",
|
||||
"Name": "Láncing",
|
||||
"Type": "konnyu",
|
||||
"VO": 4,
|
||||
"Price": 50
|
||||
},
|
||||
{
|
||||
"Id": "pikkelyvert",
|
||||
"Name": "Pikkelyvért",
|
||||
"Type": "kozepes",
|
||||
"VO": 4,
|
||||
"Price": 30
|
||||
},
|
||||
{
|
||||
"Id": "lancvert",
|
||||
"Name": "Láncvért",
|
||||
"Type": "kozepes",
|
||||
"VO": 5,
|
||||
"Price": 75
|
||||
},
|
||||
{
|
||||
"Id": "mellvert",
|
||||
"Name": "Mellvért",
|
||||
"Type": "kozepes",
|
||||
"VO": 5,
|
||||
"Price": 100
|
||||
},
|
||||
{
|
||||
"Id": "racsvert",
|
||||
"Name": "Rácsvért",
|
||||
"Type": "nehez",
|
||||
"VO": 6,
|
||||
"Price": 200
|
||||
},
|
||||
{
|
||||
"Id": "szalagvert",
|
||||
"Name": "Szalagvért",
|
||||
"Type": "nehez",
|
||||
"VO": 6,
|
||||
"Price": 250
|
||||
},
|
||||
{
|
||||
"Id": "lemezvert",
|
||||
"Name": "Lemezvért",
|
||||
"Type": "nehez",
|
||||
"VO": 7,
|
||||
"Price": 400
|
||||
},
|
||||
{
|
||||
"Id": "teljes_lemezvert",
|
||||
"Name": "Teljes lemezvért",
|
||||
"Type": "nehez",
|
||||
"VO": 8,
|
||||
"Price": 800
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"elsodleges": [
|
||||
[1],
|
||||
[2],
|
||||
[3],
|
||||
[4],
|
||||
[5],
|
||||
[6,1],
|
||||
[7,2],
|
||||
[8,3],
|
||||
[9,4],
|
||||
[10,5],
|
||||
[10,6,1],
|
||||
[10,7,2],
|
||||
[10,8,3],
|
||||
[10,9,4],
|
||||
[10,10,5],
|
||||
[10,10,6],
|
||||
[10,10,7],
|
||||
[10,10,8],
|
||||
[10,10,9],
|
||||
[10,10,10]
|
||||
],
|
||||
"ketharmados": [
|
||||
[0],
|
||||
[1],
|
||||
[2],
|
||||
[2],
|
||||
[3],
|
||||
[4],
|
||||
[4],
|
||||
[5],
|
||||
[6,1],
|
||||
[6,1],
|
||||
[7,2],
|
||||
[8,3],
|
||||
[8,3],
|
||||
[9,4],
|
||||
[10,5],
|
||||
[10,5],
|
||||
[10,6],
|
||||
[10,7],
|
||||
[10,7],
|
||||
[10,8]
|
||||
],
|
||||
"feles": [
|
||||
[0],
|
||||
[1],
|
||||
[1],
|
||||
[2],
|
||||
[2],
|
||||
[3],
|
||||
[3],
|
||||
[4],
|
||||
[4],
|
||||
[5],
|
||||
[5],
|
||||
[6],
|
||||
[6],
|
||||
[7],
|
||||
[7],
|
||||
[8],
|
||||
[8],
|
||||
[9],
|
||||
[9],
|
||||
[10]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
import {Osztaly} from "./osztaly";
|
||||
import {CelzoTB, KozelharciTB, TamadasBonusz} from "./tamadas_bonusz";
|
||||
import {KarakterTulajdonsagok, Modifier} from "./tulajdonsag";
|
||||
|
||||
describe('Tamadas Bonusz calculation', () => {
|
||||
|
||||
describe('Base Tamadas Bonusz', () => {
|
||||
test.each([
|
||||
[Osztaly.Harcos, 1, [1]],
|
||||
[Osztaly.Amazon, 6, [6,1]],
|
||||
[Osztaly.Ijasz, 20, [10,10,10]],
|
||||
[Osztaly.Tolvaj, 1, [0]],
|
||||
[Osztaly.Tolvaj, 9, [6,1]],
|
||||
[Osztaly.Pap, 17, [10,6]],
|
||||
[Osztaly.Varazslo, 1, [0]],
|
||||
[Osztaly.Varazslo, 12, [6]],
|
||||
[Osztaly.Illuzionista, 20, [10]],
|
||||
])('%s has a TB of %i at level %i', (osztaly: Osztaly, szint: number, expectedTB: number[]) => {
|
||||
const actual = TamadasBonusz(osztaly, szint)
|
||||
expect(actual).toEqual(expectedTB)
|
||||
})
|
||||
});
|
||||
|
||||
describe('CelzoTB', () => {
|
||||
const szint = 10
|
||||
const tulajdonsagok: KarakterTulajdonsagok = {
|
||||
t_ugy: 17,
|
||||
t_kar: 3,
|
||||
t_bol: 3,
|
||||
t_egs: 3,
|
||||
t_ero: 3,
|
||||
t_int: 3,
|
||||
}
|
||||
const modifier = Modifier(tulajdonsagok.t_ugy)
|
||||
|
||||
it('should be equal base + ugyesseg modifier', () => {
|
||||
const osztaly = Osztaly.Tolvaj
|
||||
const base = TamadasBonusz(osztaly, szint)
|
||||
const expected = base.map(x => x + modifier)
|
||||
|
||||
const actual = CelzoTB({
|
||||
osztaly,
|
||||
szint,
|
||||
tulajdonsagok
|
||||
})
|
||||
|
||||
expect(actual).toEqual(expected)
|
||||
});
|
||||
it('should double the first base TB for Íjász', () => {
|
||||
const osztaly = Osztaly.Ijasz
|
||||
const base = TamadasBonusz(osztaly, szint)
|
||||
const ijaszDoubleBase = [base[0], ...base]
|
||||
const expected = ijaszDoubleBase.map(x => x + modifier)
|
||||
|
||||
const actual = CelzoTB({
|
||||
osztaly,
|
||||
szint,
|
||||
tulajdonsagok
|
||||
})
|
||||
|
||||
expect(actual).toEqual(expected)
|
||||
});
|
||||
});
|
||||
|
||||
describe('KozelharciTB', () => {
|
||||
const szint = 10
|
||||
const tulajdonsagok: KarakterTulajdonsagok = {
|
||||
t_ugy: 3,
|
||||
t_kar: 3,
|
||||
t_bol: 3,
|
||||
t_egs: 3,
|
||||
t_ero: 3,
|
||||
t_int: 3,
|
||||
}
|
||||
const modifier = Modifier(tulajdonsagok.t_ero)
|
||||
|
||||
it('should be equal base + ero modifier', () => {
|
||||
const osztaly = Osztaly.Tolvaj
|
||||
const base = TamadasBonusz(osztaly, szint)
|
||||
const expected = base.map(x => x + modifier)
|
||||
|
||||
const actual = KozelharciTB({
|
||||
osztaly,
|
||||
szint,
|
||||
tulajdonsagok
|
||||
})
|
||||
|
||||
expect(actual).toEqual(expected)
|
||||
});
|
||||
it('should use t_ugy for Kaloz if t_ugy > t_ero', () => {
|
||||
const osztaly = Osztaly.Kaloz
|
||||
const tulajdonsagok: KarakterTulajdonsagok = {
|
||||
t_ugy: 17,
|
||||
t_kar: 3,
|
||||
t_bol: 3,
|
||||
t_egs: 3,
|
||||
t_ero: 3,
|
||||
t_int: 3,
|
||||
}
|
||||
const modifier = Modifier(tulajdonsagok.t_ugy)
|
||||
const base = TamadasBonusz(osztaly, szint)
|
||||
const expected = base.map(x => x + modifier)
|
||||
|
||||
const actual = KozelharciTB({
|
||||
osztaly,
|
||||
szint,
|
||||
tulajdonsagok
|
||||
})
|
||||
|
||||
expect(actual).toEqual(expected)
|
||||
});
|
||||
it('should use t_ero for Kaloz if t_ero > t_ugy', () => {
|
||||
const osztaly = Osztaly.Kaloz
|
||||
const tulajdonsagok: KarakterTulajdonsagok = {
|
||||
t_ugy: 3,
|
||||
t_kar: 3,
|
||||
t_bol: 3,
|
||||
t_egs: 3,
|
||||
t_ero: 13,
|
||||
t_int: 3,
|
||||
}
|
||||
const modifier = Modifier(tulajdonsagok.t_ero)
|
||||
const base = TamadasBonusz(osztaly, szint)
|
||||
const expected = base.map(x => x + modifier)
|
||||
|
||||
const actual = KozelharciTB({
|
||||
osztaly,
|
||||
szint,
|
||||
tulajdonsagok
|
||||
})
|
||||
|
||||
expect(actual).toEqual(expected)
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
import {Osztaly} from "./osztaly";
|
||||
import TamadasBonuszTabla from "./tamadas_bonus_tabla.json";
|
||||
import {Modifier} from "./tulajdonsag";
|
||||
import {KarakterInputs} from "./karakter";
|
||||
|
||||
export function TamadasBonusz(osztaly: Osztaly, szint: number = 1) : number[] {
|
||||
let base = []
|
||||
switch (osztaly){
|
||||
case Osztaly.Barbar:
|
||||
case Osztaly.Amazon:
|
||||
case Osztaly.Ijasz:
|
||||
case Osztaly.Kaloz:
|
||||
case Osztaly.Harcos:
|
||||
base = TamadasBonuszTabla['elsodleges'];
|
||||
break;
|
||||
case Osztaly.Pap:
|
||||
case Osztaly.Tolvaj:
|
||||
base = TamadasBonuszTabla['ketharmados'];
|
||||
break;
|
||||
case Osztaly.Varazslo:
|
||||
case Osztaly.Illuzionista:
|
||||
base = TamadasBonuszTabla['feles'];
|
||||
break;
|
||||
}
|
||||
return [...base[szint-1]]
|
||||
}
|
||||
|
||||
export function KozelharciTB(karakter : Pick<KarakterInputs, 'szint' | 'tulajdonsagok' | 'osztaly'>): number[] {
|
||||
const base = TamadasBonusz(karakter.osztaly, karakter.szint);
|
||||
let modifier = Modifier(karakter.tulajdonsagok.t_ero)
|
||||
if (karakter.osztaly === Osztaly.Kaloz && karakter.tulajdonsagok.t_ugy > karakter.tulajdonsagok.t_ero) {
|
||||
modifier = Modifier(karakter.tulajdonsagok.t_ugy)
|
||||
}
|
||||
return base.map(v => v + modifier)
|
||||
}
|
||||
export function CelzoTB(karakter : Pick<KarakterInputs, 'szint' | 'tulajdonsagok' | 'osztaly'>): number[] {
|
||||
let base = TamadasBonusz(karakter.osztaly, karakter.szint)
|
||||
if (karakter.osztaly === Osztaly.Ijasz) {
|
||||
base = [base[0], ...base]
|
||||
}
|
||||
return base.map(v => v + Modifier(karakter.tulajdonsagok.t_ugy))
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
import {d6} from "./kockak";
|
||||
import {Faj} from "./faj";
|
||||
import {KarakterInputs} from "./karakter";
|
||||
|
||||
export enum Tulajdonsag {
|
||||
Ero = 't_ero',
|
||||
Ugyesseg = 't_ugy',
|
||||
Egeszseg = 't_egs',
|
||||
Intelligencia = 't_int',
|
||||
Bolcsesseg = 't_bol',
|
||||
Karizma = 't_kar',
|
||||
}
|
||||
|
||||
export type KarakterTulajdonsagok = Record<Tulajdonsag, number>
|
||||
|
||||
export const TulajdonsagIDs = [
|
||||
Tulajdonsag.Ero,
|
||||
Tulajdonsag.Ugyesseg,
|
||||
Tulajdonsag.Egeszseg,
|
||||
Tulajdonsag.Intelligencia,
|
||||
Tulajdonsag.Bolcsesseg,
|
||||
Tulajdonsag.Karizma
|
||||
]
|
||||
|
||||
export const TulajdonsagDefaults: KarakterTulajdonsagok = {
|
||||
t_ero: 10,
|
||||
t_ugy: 10,
|
||||
t_egs: 10,
|
||||
t_int: 10,
|
||||
t_bol: 10,
|
||||
t_kar: 10,
|
||||
}
|
||||
|
||||
export function TulajdonsagLabel(tul: Tulajdonsag) : string {
|
||||
switch (tul) {
|
||||
case Tulajdonsag.Bolcsesseg: return 'Bölcsesség';
|
||||
case Tulajdonsag.Ero: return 'Erő';
|
||||
case Tulajdonsag.Ugyesseg: return 'Ügyesség';
|
||||
case Tulajdonsag.Egeszseg: return 'Egészség';
|
||||
case Tulajdonsag.Intelligencia: return 'Intelligencia';
|
||||
case Tulajdonsag.Karizma: return 'Karizma';
|
||||
}
|
||||
}
|
||||
|
||||
function rollAbility() {
|
||||
let min = 6;
|
||||
let sum = 0;
|
||||
let rolls: number[] = []
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const roll = d6();
|
||||
if (roll < min) {
|
||||
min = roll;
|
||||
}
|
||||
sum += roll;
|
||||
rolls.push(roll)
|
||||
}
|
||||
const result = sum - min;
|
||||
console.log("Rolled: " + rolls + " got: " + result)
|
||||
return result;
|
||||
}
|
||||
|
||||
export function RollAllAbilities() : KarakterTulajdonsagok {
|
||||
const response = {...TulajdonsagDefaults}
|
||||
for (const key of TulajdonsagIDs) {
|
||||
response[key] = rollAbility()
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
export const Modifier = (val : number) => Math.floor(val / 3) - 3
|
||||
|
||||
export function TulajdonsagModosito(tulajdonsagok: KarakterTulajdonsagok): KarakterTulajdonsagok {
|
||||
let response: KarakterTulajdonsagok = { ...tulajdonsagok }
|
||||
for (const key of TulajdonsagIDs) {
|
||||
response[key] = Modifier(tulajdonsagok[key])
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
// noinspection OverlyComplexFunctionJS,FunctionTooLongJS
|
||||
function tulajdonsagModositokPerFaj(tul: Tulajdonsag, faj: Faj) : number {
|
||||
switch (faj) {
|
||||
case Faj.Birodalmi: switch (tul) {
|
||||
case Tulajdonsag.Egeszseg: return -1;
|
||||
case Tulajdonsag.Intelligencia: return +1;
|
||||
default: return 0;
|
||||
}
|
||||
case Faj.Eszaki: switch (tul) {
|
||||
case Tulajdonsag.Ero: return +1;
|
||||
case Tulajdonsag.Bolcsesseg: return -1;
|
||||
default: return 0;
|
||||
}
|
||||
case Faj.Etuniai: switch (tul) {
|
||||
case Tulajdonsag.Egeszseg: return +1;
|
||||
case Tulajdonsag.Bolcsesseg: return -1;
|
||||
default: return 0
|
||||
}
|
||||
case Faj.Osember: switch (tul) {
|
||||
case Tulajdonsag.Ero: return +1;
|
||||
case Tulajdonsag.Egeszseg: return +1;
|
||||
case Tulajdonsag.Intelligencia: return -1;
|
||||
case Tulajdonsag.Bolcsesseg: return -1;
|
||||
default: return 0
|
||||
}
|
||||
case Faj.Elf: switch (tul) {
|
||||
case Tulajdonsag.Egeszseg: return -1;
|
||||
case Tulajdonsag.Ugyesseg: return +1;
|
||||
default: return 0;
|
||||
}
|
||||
case Faj.Felork: switch (tul) {
|
||||
case Tulajdonsag.Ero: return +1;
|
||||
case Tulajdonsag.Egeszseg: return +1;
|
||||
case Tulajdonsag.Karizma: return -2;
|
||||
default: return 0;
|
||||
}
|
||||
case Faj.Felszerzet: switch (tul) {
|
||||
case Tulajdonsag.Ero: return -1;
|
||||
case Tulajdonsag.Ugyesseg: return +1;
|
||||
default: return 0;
|
||||
}
|
||||
case Faj.Gnom: switch (tul) {
|
||||
case Tulajdonsag.Ero: return -1;
|
||||
case Tulajdonsag.Intelligencia: return +1;
|
||||
default: return 0;
|
||||
}
|
||||
case Faj.Torpe: switch (tul) {
|
||||
case Tulajdonsag.Egeszseg: return +1;
|
||||
case Tulajdonsag.Karizma: return -1;
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
export function TulajdonsagModositokFajokra(tul: Tulajdonsag) {
|
||||
return (faj: Faj) => tulajdonsagModositokPerFaj(tul, faj);
|
||||
}
|
||||
|
||||
export function TulajdonsagokFajjal(tulajdonsagok: KarakterTulajdonsagok, faj: Faj): KarakterTulajdonsagok {
|
||||
return {
|
||||
[Tulajdonsag.Ero]: tulajdonsagok.t_ero + tulajdonsagModositokPerFaj(Tulajdonsag.Ero, faj),
|
||||
[Tulajdonsag.Ugyesseg]: tulajdonsagok.t_ugy + tulajdonsagModositokPerFaj(Tulajdonsag.Ugyesseg, faj),
|
||||
[Tulajdonsag.Egeszseg]: tulajdonsagok.t_egs + tulajdonsagModositokPerFaj(Tulajdonsag.Egeszseg, faj),
|
||||
[Tulajdonsag.Intelligencia]: tulajdonsagok.t_int + tulajdonsagModositokPerFaj(Tulajdonsag.Intelligencia, faj),
|
||||
[Tulajdonsag.Bolcsesseg]: tulajdonsagok.t_bol + tulajdonsagModositokPerFaj(Tulajdonsag.Bolcsesseg, faj),
|
||||
[Tulajdonsag.Karizma]: tulajdonsagok.t_kar + tulajdonsagModositokPerFaj(Tulajdonsag.Karizma, faj),
|
||||
}
|
||||
}
|
||||
|
||||
export function TulajdonsagokTotal(karakter: Pick<KarakterInputs, 'tulajdonsagok' | 'faj' | 'tulajdonsagNovelesek'>): KarakterTulajdonsagok {
|
||||
const response = TulajdonsagokFajjal(karakter.tulajdonsagok, karakter.faj)
|
||||
for (const tulajdonsag of karakter.tulajdonsagNovelesek) {
|
||||
response[tulajdonsag] += 1
|
||||
}
|
||||
return response
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
*.css
|
||||
@@ -0,0 +1,20 @@
|
||||
.form-field-error {
|
||||
display: block;
|
||||
color: #8c0000;
|
||||
}
|
||||
|
||||
form label {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
/* Chrome, Safari, Edge, Opera */
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Firefox */
|
||||
input[type=number] {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
import React, {useState} from 'react';
|
||||
import './CreateCharacter.css'
|
||||
import {Faj} from "../domain-models/faj";
|
||||
import {Osztaly, SetFelszerelesForChangedOsztaly} from "../domain-models/osztaly"
|
||||
import FajSelector from "../components/FajSelector";
|
||||
import Tulajdonsagok from "../components/Tulajdonsagok";
|
||||
import OsztalySelector from "../components/OsztalySelector";
|
||||
import KarakterKepzettsegek from "../components/KarakterKepzettsegek";
|
||||
import {KarakterTulajdonsagok, TulajdonsagokFajjal} from "../domain-models/tulajdonsag";
|
||||
import MasodlagosErtekek from "../components/MasodlagosErtekek";
|
||||
import {
|
||||
AvailableKezpettsegList,
|
||||
GetKepzettsegListaN,
|
||||
GetNumberOfKepzettsegek,
|
||||
KepzettsegId,
|
||||
SetDefaultKepzettsegek,
|
||||
SetDefaultTolvajKepzettsegek,
|
||||
} from "../domain-models/kepzettsegek";
|
||||
import {CreatePDF} from "../pdf/character.pdf";
|
||||
import {KarakterDefaults} from "../domain-models/karakter";
|
||||
import {CalculateMasodlagosErtekek} from "../domain-models/masodlagos_ertekek";
|
||||
import {KarakterInputToPdfView} from "../pdf/karakter_pdf_view";
|
||||
import JellemSelector from "../components/JellemSelector";
|
||||
import {CanLevelUp, LevelDown, LevelUp} from "../domain-models/level";
|
||||
import {Card} from "react-bootstrap";
|
||||
import LevelUps from "../components/LevelUps";
|
||||
import HarcosFegyverSpecializacio from "../components/HarcosFegyverSpecializacio";
|
||||
import Felszereles from '../components/Felszereles';
|
||||
import { KarakterFelszereles } from '../domain-models/felszereles';
|
||||
import {Faro} from "@grafana/faro-web-sdk";
|
||||
|
||||
function CreateCharacterPage(props: {faro?: Faro}) {
|
||||
const {faro} = props
|
||||
|
||||
let [karakter, changeKarakter] = useState(KarakterDefaults)
|
||||
|
||||
const tulajdonsagokFajjal = TulajdonsagokFajjal(karakter.tulajdonsagok, karakter.faj)
|
||||
|
||||
const changeKepzettseg = (k: KepzettsegId[]) => changeKarakter({...karakter, kepzettsegek: k})
|
||||
const changeTolvajKepzettseg = (tk?: KepzettsegId[]) => changeKarakter({...karakter, tolvajKepzettsegek: tk})
|
||||
SetDefaultTolvajKepzettsegek(karakter, changeTolvajKepzettseg)
|
||||
SetDefaultKepzettsegek({...karakter, tulajdonsagok: tulajdonsagokFajjal}, changeKepzettseg)
|
||||
const availableKepzettsegList = AvailableKezpettsegList(karakter.osztaly)
|
||||
const setFelszereles = (f: KarakterFelszereles) => changeKarakter({...karakter, felszereles: f})
|
||||
SetFelszerelesForChangedOsztaly(karakter.osztaly, karakter.felszereles, setFelszereles)
|
||||
|
||||
const levelUp = () => LevelUp(karakter, changeKarakter)
|
||||
const levelDown = () => LevelDown(karakter, changeKarakter)
|
||||
|
||||
const canLevelUp = CanLevelUp(karakter)
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='container-fluid p-5 bg-black text-white text-center'>
|
||||
<h1>Karakter létrehozása</h1>
|
||||
</div>
|
||||
<div className='p-3'>
|
||||
<form onSubmit={ async (event) => event.preventDefault() }>
|
||||
<div className='row'>
|
||||
<h5 className='col align-self-center'>Származás</h5>
|
||||
</div>
|
||||
<div className='row m-2'>
|
||||
<label className='col-md-2 col-sm-3 col-form-label' >Név</label>
|
||||
<input className='col form-control'
|
||||
value={karakter.name}
|
||||
onChange={(e) => changeKarakter({...karakter, name: e.target.value})}/>
|
||||
{!karakter.name && <span className='form-field-error'>A karaktered nem mászkálhat névtelenül a világban!</span>}
|
||||
</div>
|
||||
<div className='row m-2'>
|
||||
<label className='col-md-2 col-sm-3 col-form-label' >Nem</label>
|
||||
<input className='col form-control'
|
||||
value={karakter.nem}
|
||||
onChange={(e) => changeKarakter({...karakter, nem: e.target.value})}/>
|
||||
</div>
|
||||
<div className='row m-2'>
|
||||
<label className='col-md-2 col-sm-3 col-form-label' >Kor</label>
|
||||
<input className='col form-control'
|
||||
value={karakter.kor}
|
||||
type={"number"}
|
||||
onChange={(e) => changeKarakter({...karakter, kor: Number(e.target.value)})}/>
|
||||
</div>
|
||||
<JellemSelector selected={karakter.jellem} changeJellem={(val) => changeKarakter({...karakter, jellem: val})} />
|
||||
<div className='row m-2'>
|
||||
<label className='col-md-2 col-sm-3 col-form-label' >Választott istenség</label>
|
||||
<input className='col form-control'
|
||||
value={karakter.isten}
|
||||
onChange={(e) => changeKarakter({...karakter, isten: e.target.value})}/>
|
||||
</div>
|
||||
<FajSelector
|
||||
changeFaj={(faj: Faj) => changeKarakter({...karakter, faj: faj})}
|
||||
faj={karakter.faj}
|
||||
/>
|
||||
<hr/>
|
||||
<Tulajdonsagok
|
||||
currentFaj={karakter.faj}
|
||||
tulajdonsagok={karakter.tulajdonsagok}
|
||||
changeTulajdonsagok={(tul: KarakterTulajdonsagok) => changeKarakter({...karakter, tulajdonsagok: tul})}
|
||||
/>
|
||||
<hr />
|
||||
<div className='row'>
|
||||
<h5 className='col align-self-center'>Tanult</h5>
|
||||
</div>
|
||||
<OsztalySelector
|
||||
currentFaj={karakter.faj}
|
||||
currentOsztaly={karakter.osztaly}
|
||||
changeOsztaly={(o: Osztaly) =>
|
||||
changeKarakter({
|
||||
...karakter,
|
||||
osztaly: o,
|
||||
harcosSpecializaciok: (o === Osztaly.Harcos && karakter.harcosSpecializaciok.length === 0) ? ['hosszu_kard'] : karakter.harcosSpecializaciok,
|
||||
})}
|
||||
/>
|
||||
{karakter.osztaly === Osztaly.Harcos &&
|
||||
<div className='mb-6'>
|
||||
<HarcosFegyverSpecializacio
|
||||
specialization={karakter.harcosSpecializaciok[0]}
|
||||
existingSpecializations={karakter.harcosSpecializaciok}
|
||||
changeSpecialization={(spec: string) => changeKarakter({...karakter, harcosSpecializaciok: [spec, ...karakter.harcosSpecializaciok.slice(1)]})}
|
||||
szint={1}
|
||||
/>
|
||||
</div>}
|
||||
<KarakterKepzettsegek
|
||||
getKepzettsegListaN={GetKepzettsegListaN(karakter)}
|
||||
numberOfKepzettsegek={GetNumberOfKepzettsegek(tulajdonsagokFajjal.t_int, karakter.faj, availableKepzettsegList.length)}
|
||||
kepzettsegek={karakter.kepzettsegek}
|
||||
changeKepzettsegek={changeKepzettseg}
|
||||
tolvajKepzettsegek={karakter.tolvajKepzettsegek || []}
|
||||
changeTolvajKepzettsegek={changeTolvajKepzettseg}
|
||||
/>
|
||||
|
||||
<hr />
|
||||
<MasodlagosErtekek {...CalculateMasodlagosErtekek({...karakter, tulajdonsagok: tulajdonsagokFajjal, szint: 1, hpRolls: []})} />
|
||||
|
||||
<hr />
|
||||
|
||||
<LevelUps key={'level-ups'} karakter={karakter} changeKarakter={changeKarakter} />
|
||||
|
||||
{karakter.szint > 1 && <hr />}
|
||||
<div className='d-grid gap-2 m-5'>
|
||||
{canLevelUp && <button className='btn btn-dark btn-lg' type='button' onClick={levelUp}>Szintlépés! ⇧</button> }
|
||||
{!canLevelUp && karakter.szint < 10 &&
|
||||
<Card className='col text-center p-3'>Elérted a fajod szint limitjét</Card>}
|
||||
{karakter.szint > 1 && <button className='btn btn-dark btn-lg' type='button' onClick={levelDown}>Visszalépés! ⇩</button> }
|
||||
</div>
|
||||
|
||||
|
||||
<hr />
|
||||
|
||||
<Felszereles osztaly={karakter.osztaly} felszereles={karakter.felszereles} changeFelszereles={setFelszereles} harcosSpec={karakter.harcosSpecializaciok} />
|
||||
|
||||
<div className='d-grid gap-2 m-5'>
|
||||
<button className='btn btn-danger btn-lg' type='button' onClick={async () => {
|
||||
faro?.api.pushEvent('character_created', {
|
||||
osztaly: karakter.osztaly,
|
||||
szint: karakter.szint.toString()
|
||||
})
|
||||
await CreatePDF(KarakterInputToPdfView(karakter))
|
||||
}}>Létrehozás</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default CreateCharacterPage;
|
||||
@@ -0,0 +1,90 @@
|
||||
import {KarakterPdfView, KepzettsegPdfView} from "./karakter_pdf_view";
|
||||
import {PDFDocument, rgb} from "pdf-lib";
|
||||
import fontkit from '@pdf-lib/fontkit'
|
||||
import {SignedNumberToText} from "../components/Helpers";
|
||||
import download from "downloadjs";
|
||||
import {DrawTulajdonsagok} from "./tulajdonsagok.pdf";
|
||||
import {DrawMentok} from "./mentok.pdf";
|
||||
import {DrawMagic} from "./magic.pdf";
|
||||
import {DrawMasodlagosErtekek} from './masodlagos_ertekek.pdf'
|
||||
import {DrawOsztalySpecialsPage} from './osztaly_specials.pdf'
|
||||
import {DrawFegyverek} from "./fegyverek.pdf";
|
||||
|
||||
function drawBaseInfo(karakter: KarakterPdfView, draw: (text: string, x : number ,y: number, scale: number) => void) {
|
||||
draw(karakter.Name, 60, 710, 1)
|
||||
draw(karakter.Nem, 454, 710, 1)
|
||||
draw(karakter.Kor.toString(), 454, 690, 1)
|
||||
draw(karakter.Isten, 454, 670, 1)
|
||||
draw(karakter.Osztaly, 60, 672, 1)
|
||||
draw(karakter.Szint, karakter.Szint.length > 1 ? 252 : 264, 682, 3)
|
||||
draw(karakter.Faj, 302, 710, 1)
|
||||
draw(karakter.Jellem, 302, 672, karakter.Jellem.length > 17 ? 11/12 : 1)
|
||||
}
|
||||
|
||||
function DrawKepzettsegek(draw: (text: string, x: number, y: number) => void, kepzettsegek: KepzettsegPdfView[], startFrom: number) {
|
||||
for (let i = 0; i < kepzettsegek.length; i++) {
|
||||
let kepzettseg = kepzettsegek[i]
|
||||
draw(kepzettseg.KepzettsegName, 60, startFrom - (i * 18))
|
||||
const kepzettsegModifier = SignedNumberToText(kepzettseg.KepzettsegModifier)
|
||||
draw(kepzettsegModifier, kepzettsegModifier.length > 2 ? 172 : 175, startFrom - (i * 18))
|
||||
}
|
||||
}
|
||||
|
||||
function DrawFelszereles(draw: (text: string, x: number, y:number) => void, felszereles: string[]) {
|
||||
const startFrom = 337
|
||||
for (let i = 0; i < felszereles.length; i++) {
|
||||
const item = felszereles[i];
|
||||
draw(item, 390, startFrom - (i * 18))
|
||||
}
|
||||
}
|
||||
|
||||
export async function CreatePDF(karakter: KarakterPdfView) {
|
||||
|
||||
const existingPdfBytes = await fetch('/km_karakterlap_hysteria_1.2.pdf').then(res => res.arrayBuffer())
|
||||
const pdfDoc = await PDFDocument.load(existingPdfBytes)
|
||||
pdfDoc.registerFontkit(fontkit)
|
||||
|
||||
const fontBytes = await fetch('/Merienda-Regular.ttf').then(res => res.arrayBuffer())
|
||||
const pdfFont = await pdfDoc.embedFont(fontBytes)
|
||||
// const pdfFont = await pdfDoc.embedFont(StandardFonts.TimesNewRoman)
|
||||
const fontSizeBase = 12
|
||||
|
||||
const page = pdfDoc.getPage(0)
|
||||
|
||||
function drawText(text: string, x: number, y: number, fontScale = 1, shade = 0) {
|
||||
page.drawText(text, {
|
||||
x: x,
|
||||
y: y,
|
||||
size: fontSizeBase * fontScale,
|
||||
font: pdfFont,
|
||||
color: rgb(shade, shade, shade),
|
||||
})
|
||||
}
|
||||
|
||||
drawBaseInfo(karakter, drawText);
|
||||
|
||||
DrawTulajdonsagok(page, karakter.Tulajdonsagok, fontSizeBase, pdfFont);
|
||||
|
||||
DrawMasodlagosErtekek(page, karakter, fontSizeBase, pdfFont);
|
||||
|
||||
DrawMentok(page, karakter, fontSizeBase, pdfFont);
|
||||
|
||||
DrawKepzettsegek(drawText, karakter.Kepzettsegek, 337);
|
||||
const nextKepzettsegFrom = 337 - (karakter.Kepzettsegek.length * 18)
|
||||
DrawKepzettsegek(drawText, karakter.TolvajKepzettsegek, nextKepzettsegFrom)
|
||||
|
||||
DrawFelszereles(drawText, karakter.Felszereles)
|
||||
|
||||
DrawFegyverek(karakter, pdfFont, fontSizeBase, page)
|
||||
|
||||
DrawMagic(page, fontSizeBase, pdfFont, karakter.NapiMemorizalhatoVarazslatok, karakter.VarazslatMentokNF)
|
||||
|
||||
const secondPage = pdfDoc.addPage()
|
||||
const fontBoldBytes = await fetch('/Merienda-Bold.ttf').then(res => res.arrayBuffer())
|
||||
const fontBold = await pdfDoc.embedFont(fontBoldBytes)
|
||||
DrawOsztalySpecialsPage(secondPage, pdfFont, fontBold, karakter)
|
||||
|
||||
const pdfBytes = await pdfDoc.save();
|
||||
download(pdfBytes, karakter.Name + ".pdf", "application/pdf");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import {KarakterPdfView} from "./karakter_pdf_view";
|
||||
import {PDFFont, PDFPage} from "pdf-lib";
|
||||
import {SignedNumberToText} from "../components/Helpers";
|
||||
|
||||
function fitTextInWidth(font: PDFFont, text: string, startingSize: number, maxWidth: number): number {
|
||||
let size = startingSize
|
||||
while(font.widthOfTextAtSize(text, size) > maxWidth) {
|
||||
size--
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
export function DrawFegyverek(karakter: KarakterPdfView, pdfFont: PDFFont, fontSizeBase: number, page: PDFPage) {
|
||||
const startFrom = 337
|
||||
for (let i = 0; i < karakter.Fegyverek.length && i < 3; i++) {
|
||||
const fegyver = karakter.Fegyverek[i];
|
||||
const size = fitTextInWidth(pdfFont, fegyver.Name, fontSizeBase, 60)
|
||||
page.drawText(fegyver.Name, {
|
||||
x: 200,
|
||||
y: startFrom - (i * 18) + ((18 - pdfFont.heightAtSize(size)) / 3),
|
||||
size: size,
|
||||
font: pdfFont,
|
||||
})
|
||||
page.drawText(SignedNumberToText(fegyver.TamadoBonusz), {
|
||||
x: 265,
|
||||
y: startFrom - (i * 18),
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
})
|
||||
const damageSize = fitTextInWidth(pdfFont, fegyver.Damage, fontSizeBase, 24)
|
||||
page.drawText(fegyver.Damage, {
|
||||
x: 291,
|
||||
y: startFrom - (i * 18) + ((18 - pdfFont.heightAtSize(damageSize)) / 3),
|
||||
size: damageSize,
|
||||
font: pdfFont,
|
||||
})
|
||||
const critSize = fitTextInWidth(pdfFont, fegyver.Crit, fontSizeBase, 35)
|
||||
page.drawText(fegyver.Crit, {
|
||||
x: 318,
|
||||
y: startFrom - (i * 18) + ((18 - pdfFont.heightAtSize(critSize)) / 3),
|
||||
size: critSize,
|
||||
font: pdfFont,
|
||||
})
|
||||
page.drawText(fegyver.Range, {
|
||||
x: 360,
|
||||
y: startFrom - (i * 18),
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
import {KarakterTulajdonsagok, Modifier, TulajdonsagModosito, TulajdonsagokTotal} from "../domain-models/tulajdonsag";
|
||||
import {Mentok, MentokAlap, MentoModositok} from "../domain-models/mentok";
|
||||
import {Kepzettseg, Kepzettsegek} from "../domain-models/kepzettsegek";
|
||||
import {CalculateMasodlagosErtekek} from "../domain-models/masodlagos_ertekek";
|
||||
import {Faj, FajLabel} from "../domain-models/faj";
|
||||
import {Osztaly, OsztalyLabel, Skill} from "../domain-models/osztaly";
|
||||
import {CelzoTB, KozelharciTB} from "../domain-models/tamadas_bonusz";
|
||||
import {KarakterInputs} from "../domain-models/karakter";
|
||||
import {CalculateVarazslatMentokNF, NapiVarazslatok} from "../domain-models/memorizalt_varazslatok";
|
||||
import {GetJellem} from "../domain-models/jellem";
|
||||
import {Fegyver, GetFegyverek, GetPajzs, GetPancel} from '../domain-models/felszereles'
|
||||
import {SignedNumberToText} from "../components/Helpers";
|
||||
import {OsztalySkillsTordelt} from "./osztaly_skills";
|
||||
|
||||
export interface KepzettsegPdfView {
|
||||
KepzettsegName: string
|
||||
KepzettsegModifier: number
|
||||
}
|
||||
|
||||
export interface FegyverPdfView {
|
||||
Name: string
|
||||
TamadoBonusz: number
|
||||
Damage: string
|
||||
Crit: string
|
||||
Range: string
|
||||
}
|
||||
|
||||
export interface KarakterPdfView {
|
||||
Name: string
|
||||
Nem: string
|
||||
Kor: number
|
||||
Isten: string
|
||||
Jellem: string
|
||||
Faj: string
|
||||
Osztaly: string
|
||||
OsztalySkills: Skill[],
|
||||
Tulajdonsagok: KarakterTulajdonsagok,
|
||||
TulajdonsagModositok: KarakterTulajdonsagok,
|
||||
Szint: string
|
||||
HP: number
|
||||
VO: number
|
||||
Mozgas: number
|
||||
Kezdemenyezes: number
|
||||
KozelharciTB: number[]
|
||||
CelzoTB: number[]
|
||||
MentokAlap: Mentok
|
||||
MentoModositok: Mentok
|
||||
MentokModositokkal: Mentok
|
||||
Kepzettsegek: KepzettsegPdfView[]
|
||||
TolvajKepzettsegek: KepzettsegPdfView[]
|
||||
NapiMemorizalhatoVarazslatok: number[]
|
||||
VarazslatMentokNF : number[]
|
||||
Felszereles: string[]
|
||||
PancelVO: number
|
||||
PajzsVO: number
|
||||
Fegyverek: FegyverPdfView[]
|
||||
}
|
||||
|
||||
export function KarakterInputToPdfView(karakter: KarakterInputs): KarakterPdfView {
|
||||
const tulajdonsagok = TulajdonsagokTotal(karakter)
|
||||
karakter = {...karakter, tulajdonsagok}
|
||||
const tulajdonsagModositok = TulajdonsagModosito(tulajdonsagok)
|
||||
const masodlagosErtekek = CalculateMasodlagosErtekek(karakter)
|
||||
const pancel = GetPancel(karakter.felszereles.pancelID)
|
||||
const pajzs = GetPajzs(karakter.felszereles.pajzsID)
|
||||
const mozgas = karakter.faj === Faj.Torpe || pancel?.Type === 'nehez' || pancel?.Type === 'kozepes' ? 20 : 30
|
||||
const kezdemenyezes = tulajdonsagModositok.t_ugy + (karakter.osztaly === Osztaly.Tolvaj ? 4 : 0)
|
||||
|
||||
const mentok = MentokAlap(karakter.osztaly, karakter.szint)
|
||||
const mentoModositok = MentoModositok(tulajdonsagModositok)
|
||||
|
||||
const NapiMemorizalhatoVarazslatok = NapiVarazslatok(karakter)
|
||||
const VarazslatMentokNF = CalculateVarazslatMentokNF(karakter)
|
||||
const fegyverek = GetFegyverek(karakter.felszereles.fegyverIDk)
|
||||
|
||||
const felszereles = [ pancel?.Name, pajzs?.Name, ...fegyverek.filter(f => f.Id !== 'okol').map(f => f.Name.includes('és') ? f.Name.split(' ')[0] : f.Name) ].filter(x => !!x) as string[]
|
||||
|
||||
return {
|
||||
Faj: FajLabel(karakter.faj),
|
||||
Isten: karakter.isten || "",
|
||||
Jellem: GetJellem(karakter.jellem).Label,
|
||||
Kor: karakter.kor,
|
||||
Name: karakter.name,
|
||||
Nem: karakter.nem || "",
|
||||
Tulajdonsagok: karakter.tulajdonsagok,
|
||||
Osztaly: OsztalyLabel(karakter.osztaly),
|
||||
OsztalySkills: OsztalySkillsTordelt(karakter.osztaly),
|
||||
Szint: karakter.szint.toString(),
|
||||
Kepzettsegek: karakter.kepzettsegek.map(id => mapKepzettsegToPdfView(Kepzettsegek[id], tulajdonsagok, karakter.szint)),
|
||||
TolvajKepzettsegek: karakter.tolvajKepzettsegek?.map(id => mapKepzettsegToPdfView(Kepzettsegek[id], tulajdonsagok, karakter.szint)) || [],
|
||||
TulajdonsagModositok: tulajdonsagModositok,
|
||||
|
||||
HP: masodlagosErtekek.HP,
|
||||
VO: masodlagosErtekek.VO,
|
||||
Mozgas: mozgas,
|
||||
Kezdemenyezes: kezdemenyezes,
|
||||
KozelharciTB: KozelharciTB(karakter),
|
||||
CelzoTB: CelzoTB(karakter),
|
||||
|
||||
MentoModositok: mentoModositok,
|
||||
MentokAlap: mentok,
|
||||
MentokModositokkal: masodlagosErtekek.Mentok,
|
||||
|
||||
NapiMemorizalhatoVarazslatok,
|
||||
VarazslatMentokNF,
|
||||
Felszereles: felszereles,
|
||||
PajzsVO: pajzs?.VO ?? 0,
|
||||
PancelVO: pancel?.VO ?? 0,
|
||||
Fegyverek: fegyverek.map(mapFegyverToPdfView(karakter)),
|
||||
}
|
||||
}
|
||||
|
||||
function mapKepzettsegToPdfView(kepzettseg: Kepzettseg, tulajdonsagok: KarakterTulajdonsagok, szint: number) {
|
||||
const tulajdonsagErtek = kepzettseg.Tulajdonsag.reduce((maxTulajdonsagErtek, currentTulajdonsag) =>
|
||||
(tulajdonsagok[currentTulajdonsag] > maxTulajdonsagErtek)
|
||||
? tulajdonsagok[currentTulajdonsag]
|
||||
: maxTulajdonsagErtek,
|
||||
tulajdonsagok[kepzettseg.Tulajdonsag[0]])
|
||||
|
||||
const modifier = Modifier(tulajdonsagErtek) + szint
|
||||
return {
|
||||
KepzettsegName: kepzettseg.Name,
|
||||
KepzettsegModifier: modifier,
|
||||
}
|
||||
}
|
||||
|
||||
function mapFegyverToPdfView(karakter: KarakterInputs) {
|
||||
return (fegyver: Fegyver): FegyverPdfView => {
|
||||
const simplifiedName = fegyver.Name.includes('és') ? fegyver.Name.split(' ')[0] : fegyver.Name
|
||||
const tb = fegyver.Type === 'kozelharci' ? KozelharciTB(karakter)[0] : CelzoTB(karakter)[0]
|
||||
const tulajdonsagModositok = TulajdonsagModosito(TulajdonsagokTotal(karakter))
|
||||
let damageModifier = fegyver.Type === 'kozelharci' || (fegyver.Id === 'visszacsapo_ij' && tulajdonsagModositok.t_ero > 0) ? tulajdonsagModositok.t_ero : 0
|
||||
damageModifier += karakter.harcosSpecializaciok.filter(x => x === fegyver.Id).length * 2
|
||||
if (fegyver.Id === 'visszacsapo_ij' && tulajdonsagModositok.t_ero > 0) { // "hozzaadhato", so only add if positive
|
||||
damageModifier += tulajdonsagModositok.t_ero
|
||||
}
|
||||
if (fegyver.Ketkezes) {
|
||||
damageModifier += Math.floor(tulajdonsagModositok.t_ero / 2)
|
||||
}
|
||||
const damage = `${fegyver.NumberOfDamageDice > 1 ? fegyver.NumberOfDamageDice.toString() : ''}d${fegyver.DamageDice}${damageModifier !== 0 ? SignedNumberToText(damageModifier) : ''}`
|
||||
const critStart = fegyver.CritRangeStart - karakter.kalozKritikus.filter(x => x === fegyver.Id).length
|
||||
const crit = `${critStart < 20 ? `${critStart}-20` : '20'} x${fegyver.CritMultiplier}`
|
||||
const range = fegyver.Range === 0 ? '-' : fegyver.Range.toString()
|
||||
return {
|
||||
Name: simplifiedName,
|
||||
TamadoBonusz: tb,
|
||||
Damage: damage,
|
||||
Crit: crit,
|
||||
Range: range,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import {PDFFont, PDFPage, rgb} from "pdf-lib";
|
||||
|
||||
export function DrawMagic(page: PDFPage, fontSizeBase: number, pdfFont: PDFFont, napiVarazslatok: number[], varazsMentokNF: number[]){
|
||||
for(let i = 0; i < 6; i++) {
|
||||
const y = 247 - (i*18)
|
||||
page.drawText(i.toString(), {
|
||||
x: 210,
|
||||
y: y,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
if (i < napiVarazslatok.length) {
|
||||
page.drawText(napiVarazslatok[i].toString(), {
|
||||
x: 242,
|
||||
y: y,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(varazsMentokNF[i].toString(), {
|
||||
x: 269,
|
||||
y: y,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import {PDFFont, PDFPage} from "pdf-lib";
|
||||
import {KarakterPdfView} from "./karakter_pdf_view";
|
||||
import {SignedNumberToText} from "../components/Helpers";
|
||||
|
||||
export function DrawMasodlagosErtekek(
|
||||
page: PDFPage,
|
||||
karakter: KarakterPdfView,
|
||||
fontSizeBase: number,
|
||||
pdfFont: PDFFont)
|
||||
{
|
||||
page.drawText(karakter.Mozgas.toString(), {
|
||||
x: 162,
|
||||
y: 416,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
})
|
||||
page.drawText(SignedNumberToText(karakter.Kezdemenyezes), {
|
||||
x: 505,
|
||||
y: 416,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
})
|
||||
page.drawText(karakter.HP.toString(), {
|
||||
x: 318,
|
||||
y: 517,
|
||||
size: fontSizeBase * 1.5,
|
||||
font: pdfFont,
|
||||
})
|
||||
page.drawText(karakter.VO.toString(), {
|
||||
x: 368,
|
||||
y: 495,
|
||||
size: fontSizeBase * 3,
|
||||
font: pdfFont,
|
||||
})
|
||||
page.drawText(karakter.PancelVO.toString(), {
|
||||
x: 512,
|
||||
y: 515,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
})
|
||||
page.drawText(karakter.PajzsVO.toString(), {
|
||||
x: 512,
|
||||
y: 482,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
})
|
||||
const kozelharciTB = karakter.KozelharciTB.map(SignedNumberToText).join("/")
|
||||
|
||||
function getFontSize(length: number): number {
|
||||
switch (length) {
|
||||
case 1:
|
||||
case 2:
|
||||
return 24;
|
||||
case 3:
|
||||
return 18;
|
||||
case 4:
|
||||
return 14;
|
||||
case 5:
|
||||
return 11;
|
||||
case 6:
|
||||
return 9;
|
||||
case 7:
|
||||
return 8;
|
||||
default:
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
function getYOffset(length: number): number {
|
||||
return Math.min(length - 2, 6);
|
||||
}
|
||||
|
||||
const kozelHarciFontSize = getFontSize(kozelharciTB.length)
|
||||
page.drawText(kozelharciTB, {
|
||||
x: kozelharciTB.length > 4 ? 256 : 258,
|
||||
y: 383 + getYOffset(kozelharciTB.length),
|
||||
size: kozelHarciFontSize,
|
||||
font: pdfFont,
|
||||
})
|
||||
const celzoTB = karakter.CelzoTB.map(SignedNumberToText).join("/")
|
||||
const celzoFontSize = getFontSize(celzoTB.length)
|
||||
page.drawText(celzoTB, {
|
||||
x: celzoTB.length > 4 ? 343 : 346,
|
||||
y: 383 + getYOffset(celzoTB.length),
|
||||
size: celzoFontSize,
|
||||
font: pdfFont,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import {PDFFont, PDFPage, rgb} from "pdf-lib";
|
||||
import {KarakterPdfView} from "./karakter_pdf_view";
|
||||
import {SignedNumberToText} from "../components/Helpers";
|
||||
import {Modifier} from "../domain-models/tulajdonsag";
|
||||
|
||||
export function DrawMentok(page: PDFPage, karakter: KarakterPdfView, fontSizeBase: number, pdfFont: PDFFont) {
|
||||
const mentokAlap = karakter.MentokAlap
|
||||
page.drawText(SignedNumberToText(mentokAlap.kitartas), {
|
||||
x: 435,
|
||||
y: 613,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(mentokAlap.reflex), {
|
||||
x: 435,
|
||||
y: 580,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(mentokAlap.akaratero), {
|
||||
x: 435,
|
||||
y: 547,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(Modifier(karakter.Tulajdonsagok.t_egs)), {
|
||||
x: 475,
|
||||
y: 613,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(Modifier(karakter.Tulajdonsagok.t_ugy)), {
|
||||
x: 475,
|
||||
y: 580,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(Modifier(karakter.Tulajdonsagok.t_bol)), {
|
||||
x: 475,
|
||||
y: 547,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
const mentok = karakter.MentokModositokkal
|
||||
page.drawText(SignedNumberToText(mentok.kitartas), {
|
||||
x: 515,
|
||||
y: 613,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(mentok.reflex), {
|
||||
x: 515,
|
||||
y: 580,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(mentok.akaratero), {
|
||||
x: 515,
|
||||
y: 547,
|
||||
size: fontSizeBase,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
import {Osztaly, Skill} from "../domain-models/osztaly";
|
||||
|
||||
export function OsztalySkillsTordelt(osztaly: Osztaly) : Skill[] {
|
||||
switch (osztaly) {
|
||||
case Osztaly.Harcos: return [{
|
||||
Id: 's_harcos_harcos',
|
||||
Name: 'Harcos',
|
||||
Description: 'Speciális harci tapasztalatuknak köszönhetően minden páratlan szinten +2-t kapnak egy\n' +
|
||||
'választott fegyvertípus (pl. csatabárd, hosszúkard, stb.) sebzésére. Ez fegyverenként csak\n' +
|
||||
'egyszer választható, s arra is fölhasználható, hogy a harcos megtanulja egy egzotikus\n' +
|
||||
'fegyver használatát, amire később specializálódhat is. 9. szinttől elérhető számukra a\n' +
|
||||
'kettős specializáció: ezzel sebzésmódosítójukat az adott fegyverre +4-re emelhetik.'
|
||||
}]
|
||||
case Osztaly.Ijasz: return [
|
||||
{
|
||||
Id: 's_harcos_ijasz',
|
||||
Name: 'Íjász',
|
||||
Description: 'Íjak használatakor körönként eggyel többször támadhatnak.\n' +
|
||||
'Értenek a visszacsapó íjak használatához is.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_ijasz_vert',
|
||||
Name: 'Kötelező mozgékonyság',
|
||||
Description: 'Az íjászok nem viselhetnek nehéz vérteket.'
|
||||
}
|
||||
]
|
||||
case Osztaly.Amazon: return [
|
||||
{
|
||||
Id: 's_harcos_amazon_vert',
|
||||
Name: 'MMO vért',
|
||||
Description:
|
||||
'Az amazonok csak láncinget vagy könnyebb vérteket viselhetnek, de VO-juk Szint/2-vel\n' +
|
||||
'javul, továbbá Karizma- és Ügyességmódosítói közül a kedvezőbbet választhatják.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_amazon_csapatmunka',
|
||||
Name: 'Csapatmunka',
|
||||
Description: 'Ha kettő vagy több amazon együttesen harcol, VO-juk további 2 ponttal nő pszionikus\n' +
|
||||
'képességeik miatt.'
|
||||
},
|
||||
]
|
||||
case Osztaly.Kaloz: return [
|
||||
{
|
||||
Id: 's_harcos_kaloz_ugyes_huzas',
|
||||
Name: 'Ügyes húzás',
|
||||
Description: 'A kalózok és tengerészek ha magasabb, Ügyességbónuszukat adják hozzá közelharci\n' +
|
||||
'támadásaikhoz.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_kaloz_vasmacska',
|
||||
Name: 'Vasmacska',
|
||||
Description: 'A kalózok és tengerészek nem viselhetnek nehéz vértezetet, de VO-juk könnyű vértben\n' +
|
||||
'Szint/3-al javul.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_kaloz_kritikus',
|
||||
Name: 'Kritikus',
|
||||
Description: 'Minden harmadik szinten kiválaszthatnak egy fegyvert, amivel könnyebben okoznak\n' +
|
||||
'kritikus sebesülést, tehát pl. csatabárddal 20 helyett 19-20-on, hosszúkarddal 19-20\n' +
|
||||
'helyett 18-20-on, szablyával 18-20 helyett 17-20-on, stb. Ez a képesség 9. szintig\n' +
|
||||
'fegyverenként csak egyszer választható.'
|
||||
}]
|
||||
case Osztaly.Barbar: return [
|
||||
{
|
||||
Id: 's_harcos_barbar_eletero',
|
||||
Name: 'Túlélő',
|
||||
Description: 'A barbárok 1d12-vel dobják a Hp-jüket, -5 Hp-ig öntudatuknál vannak és\n' +
|
||||
'+1 bónuszt (10. szinttől +2, 15. szinttől +4) kapnak a mentődobásaikra.'
|
||||
},
|
||||
{
|
||||
Id: 's_harcos_barbar_iras',
|
||||
Name: 'Írástudatlan',
|
||||
Description: 'Minden barbár írástudatlanul kezdi a játékot, de ha kell,\n' +
|
||||
'később megtanulhatja a betűvetést.'
|
||||
}
|
||||
]
|
||||
case Osztaly.Pap: return [
|
||||
{
|
||||
Id: 's_pap_gyogyseb',
|
||||
Name: 'Gyógyítás vagy sebokozás',
|
||||
Description:
|
||||
'A pap az aznap már memorizált (megtanult) varázslatokat gyógyításra vagy sebek\n' +
|
||||
'okozására is fölhasználhatja. Érintésével a varázslat minden szintjéért 1d8 Hp-t gyógyít\n' +
|
||||
'vagy sebez – így pl. egy Ómen elhasználásával 2d8 Hp-t. Az így konvertált varázslat\n' +
|
||||
'természetesen elvész. Az, hogy a képesség sebek gyógyítására vagy okozására szolgál, a\n' +
|
||||
'pap istenétől függ. A békésebb istenek főleg az elsőt, a harciasabbak főleg a másodikat\n' +
|
||||
'részesítik előnyben, s vannak olyanok is, akik híveikre bízzák, hogy melyik utat választják.\n' +
|
||||
'Ha azonban a pap már eldöntötte, melyik képességben járatos, döntését többé nem\n' +
|
||||
'másíthatja meg!'
|
||||
},
|
||||
{
|
||||
Id: 's_pap_elohalott',
|
||||
Name: 'Élőholtak elűzése vagy irányítása',
|
||||
Description:
|
||||
'A papok istenük dogmájának megfelelően képesek lehetnek arra, hogy élőholt szörnyeket\n' +
|
||||
'(mint például zombikat, lidérceket vagy vámpírokat) szimbólumuk felmutatásával\n' +
|
||||
'elűzzenek vagy szolgálatukba állítsanak. Ez a képesség naponta csak egyszer (5. szinttől\n' +
|
||||
'kétszer, 10. szinttől háromszor, 15. szinttől négyszer) használható. A cselekedet a\n' +
|
||||
'következő módon működik:',
|
||||
ExtendedDescription: [
|
||||
'A pap [1d20+Kar bónusz] próbát tesz. Ennek az értékét összeveti a standard bónusztáblázattal. Az innen kiolvasható módosítót hozzáadja saját szintjéhez (ha negatív, akkor levonja). Az eredmény jelzi, hogy a pap legfeljebb milyen szintű élőholtakra lesz hatással. Ha tehát pl. a próba végeredménye 14 és a pap ötödik szintű, akkor 5+1, azaz 6. szintű a legerősebb élőhalott, amire a kísérlet sikeres. A 20-as dobás itt is automatikus siker, az 1-es automatikus kudarc.',
|
||||
'A pap [2d6+szint] szintű élőhalottat űzhet el vagy irányíthat. Először a leggyengébb élőholtakra hat, azután a következő leggyengébbekre, stb. Az elűzött élőholtak elmenekülnek a pap szeme elől és addig nem is ártanak neki és társainak, amíg a pap csapata meg nem támadja őket! Ezzel szemben a gonosz papok parancsokat adhatnak az irányított szörnyeknek. Mindkét hatás legfeljebb pár óráig tart, az élőholtak szintjétől és a körülményektől függően.',
|
||||
'Ha az összes szem előtt lévő élőholtat sikerült elűzni vagy irányítani és még maradt „a szent energiából”, akkor ismét el kell kezdeni a hatást a leggyengébb ellenségektől. Az így elűzött szörnyek megsemmisülnek, illetve irányítás esetén végleg a gonosz pap szolgálatába állnak.',
|
||||
'A két hatás egymás ellen is fölhasználható, például egy jó pap kiolthatja egy gonosz pap irányítását, de akár két gonosz pap is versenyezhet egy csapat sírlidérc „megtérítésén”.',
|
||||
]
|
||||
},
|
||||
{
|
||||
Id: 's_pap_invokacio',
|
||||
Name: 'Invokáció',
|
||||
Description:
|
||||
'A pap kérheti istene segítségét (általában nevének kimondásával), ami +1-et, ritkábban\n' +
|
||||
' +2-t ad hozzá dobásaihoz. A papok hetente annyiszor használhatják az invokációt,\n' +
|
||||
' amekkora a Bölcsességbónuszuk (de legalább egyszer).'
|
||||
}
|
||||
]
|
||||
case Osztaly.Tolvaj: return [
|
||||
{
|
||||
Id: 's_tolvaj_orvtamadas',
|
||||
Name: 'Orvtámadás',
|
||||
Description:
|
||||
'az orvtámadás akkor használható, ha a tolvaj meglepi áldozatát, tehát pl. csöndesen a\n' +
|
||||
'hátába kerül, vagy beszélgetés közben tőrt ránt és egyetlen mozdulattal gyomron szúrja.\n' +
|
||||
'Az orvtámadás minden páratlan szintért 1d6 bónusz sebzést okoz (maximuma +5d6).\n' +
|
||||
'Dobó- és lőfegyverrel is használható, és ha a tolvaj úgy dönt, illetve a használt fegyver\n' +
|
||||
'lehetővé teszi, az ellenfél elkábítására is alkalmazható.'
|
||||
},
|
||||
{
|
||||
Id: 's_tolvaj_kezdemenyezes',
|
||||
Name: 'Jobb kezdeményezés',
|
||||
Description: 'a tolvajok +4-et kapnak kezdeményezési dobásaikra.',
|
||||
},
|
||||
{
|
||||
Id: 's_tolvaj_kepzettsegek',
|
||||
Name: 'Tolvajképzettségek',
|
||||
Description:
|
||||
'Minden tolvaj jártas több olyan képzettségben, amely segíti a rejtőzködésben, a jól őrzött\n' +
|
||||
'értékek eltulajdonításában és hasonló feladatokban. A tolvajok azokat a tolvajképzettség-\n' +
|
||||
'eket is használhatják, amelyekben nem járatosak külön, de ekkor szintjük nem számít bele\n' +
|
||||
'a próbadobás módosítójába! A tolvajképzettségek listája:\n' +
|
||||
'Álcázás, Csapdák állítása és eltávolítása, Egyensúlyozás, Értékbecslés, Hallgatózás,\n' +
|
||||
'Hamisítás, Jelek olvasása, Keresés, Mászás, Megfigyelés, Méregkeverés, Osonás, Rejtőzés,\n' +
|
||||
'Szabadulóművészet, Zárnyitás és Zsebmetszés.',
|
||||
},
|
||||
]
|
||||
case Osztaly.Varazslo: return [{
|
||||
Id: 's_varazslo_varazskonyv',
|
||||
Name: 'Varázskönyv',
|
||||
Description:
|
||||
'Egy első szintű varázsló varázskönyve 6 nulladik és 3 első szintű varázslatot tartalmaz,\n' +
|
||||
'harmadik szintű kezdő karakteré ezen felül még 2 első szintűt és 2 második szintűt.\n' +
|
||||
'Az újabb varázslatokat mások könyveiből, mágikus tekercsekből vagy más módszerek\n' +
|
||||
'segítségével kell könyvébe másolnia. Az illuzionisták szintén varázskönyveket használnak\n' +
|
||||
'de eltérő mágiaformájuk miatt nem képesek a varázslói varázslatok megértésére – és viszont.'
|
||||
}]
|
||||
case Osztaly.Illuzionista: return [{
|
||||
Id: 's_illuzionista_varazskonyv',
|
||||
Name: 'Varázskönyv',
|
||||
Description:
|
||||
'Egy első szintű illuzionista varázskönyve 6 nulladik és 3 első szintű varázslatot tartalmaz,\n' +
|
||||
'harmadik szintű kezdő karakteré ezen felül még 2 első szintűt és 2 második szintűt. Az\n' +
|
||||
'újabb varázslatokat mások könyveiből, mágikus tekercsekből vagy más módszerek\n' +
|
||||
'segítségével kell könyvébe másolnia. Az varázslók szintén varázskönyveket használnak, de\n' +
|
||||
'eltérő mágiaformájuk miatt nem képesek a varázslói varázslatok megértésére – és viszont.'
|
||||
}]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import {PDFFont, PDFPage, rgb, breakTextIntoLines} from "pdf-lib";
|
||||
import {KarakterPdfView} from "./karakter_pdf_view";
|
||||
import {Skill} from "../domain-models/osztaly";
|
||||
|
||||
const maxWidth = 540
|
||||
|
||||
function drawExtendedSkillDescription(skill: Skill, font: PDFFont, baseFontSize: number, page: PDFPage, rows: number) {
|
||||
const indent = 20
|
||||
for (let j = 0; j < (skill.ExtendedDescription?.length || 0); j++) {
|
||||
const paragraph = `${j + 1}. ${skill.ExtendedDescription![j]}`
|
||||
const lines = breakTextIntoLines(paragraph, [' ', '-'], maxWidth - indent, (s) => font.widthOfTextAtSize(s, baseFontSize))
|
||||
page.drawText(paragraph, {
|
||||
x: 30 + indent,
|
||||
y: 700 - rows,
|
||||
size: baseFontSize,
|
||||
font: font,
|
||||
lineHeight: 16,
|
||||
color: rgb(0, 0, 0),
|
||||
maxWidth: maxWidth - indent,
|
||||
wordBreaks: [' ', '-']
|
||||
})
|
||||
rows += lines.length * font.heightAtSize(baseFontSize)
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
export function DrawOsztalySpecialsPage(page: PDFPage, font: PDFFont, fontBold: PDFFont, karakter: KarakterPdfView): number {
|
||||
const baseFontSize = 12
|
||||
const titleFontSize = baseFontSize * 3
|
||||
const pageCenterX = page.getWidth()/2
|
||||
const titleWidth = font.widthOfTextAtSize(karakter.Osztaly, titleFontSize)
|
||||
const titleX = pageCenterX - (titleWidth / 2)
|
||||
|
||||
page.drawText(karakter.Osztaly, {
|
||||
x: titleX,
|
||||
y: 770,
|
||||
size: titleFontSize,
|
||||
font: font,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
let rows = 0
|
||||
for (let i = 0; i < karakter.OsztalySkills.length; i++) {
|
||||
const skill = karakter.OsztalySkills[i];
|
||||
page.drawText(skill.Name, {
|
||||
x: 30,
|
||||
y: 720 - rows,
|
||||
size: baseFontSize,
|
||||
font: fontBold,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
const lines = breakTextIntoLines(skill.Description, [' ', '-'], maxWidth, (s) => font.widthOfTextAtSize(s, baseFontSize))
|
||||
page.drawText(skill.Description, {
|
||||
x: 30,
|
||||
y: 700 - rows,
|
||||
size: baseFontSize,
|
||||
font: font,
|
||||
lineHeight: 16,
|
||||
color: rgb(0, 0, 0),
|
||||
maxWidth: maxWidth,
|
||||
wordBreaks: [' ', '-']
|
||||
})
|
||||
// rows += Math.ceil(font.widthOfTextAtSize(skill.Description, baseFontSize)/textWidth)*20 + 30
|
||||
// rows += skill.Description.split('\n').length*16 + 30
|
||||
rows += lines.length * font.heightAtSize(baseFontSize)
|
||||
rows = drawExtendedSkillDescription(skill, font, baseFontSize, page, rows);
|
||||
rows += 24 // for title and spacing
|
||||
}
|
||||
return rows
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import {PDFFont, PDFPage, rgb} from "pdf-lib";
|
||||
import {KarakterTulajdonsagok, Modifier} from "../domain-models/tulajdonsag";
|
||||
import {SignedNumberToText} from "../components/Helpers";
|
||||
|
||||
export function DrawTulajdonsagok(page: PDFPage, tulajdonsagok: KarakterTulajdonsagok, fontSizeBase: number, pdfFont: PDFFont) {
|
||||
page.drawText(tulajdonsagok.t_ero.toString(), {
|
||||
x: 130,
|
||||
y: 613,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(Modifier(tulajdonsagok.t_ero)), {
|
||||
x: 176,
|
||||
y: 613,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(tulajdonsagok.t_ugy.toString(), {
|
||||
x: 130,
|
||||
y: 580,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(Modifier(tulajdonsagok.t_ugy)), {
|
||||
x: 176,
|
||||
y: 580,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(tulajdonsagok.t_egs.toString(), {
|
||||
x: 130,
|
||||
y: 547,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(Modifier(tulajdonsagok.t_egs)), {
|
||||
x: 176,
|
||||
y: 547,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(tulajdonsagok.t_int.toString(), {
|
||||
x: 130,
|
||||
y: 515,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(Modifier(tulajdonsagok.t_int)), {
|
||||
x: 176,
|
||||
y: 515,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(tulajdonsagok.t_bol.toString(), {
|
||||
x: 130,
|
||||
y: 482,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(Modifier(tulajdonsagok.t_bol)), {
|
||||
x: 176,
|
||||
y: 482,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(tulajdonsagok.t_kar.toString(), {
|
||||
x: 130,
|
||||
y: 449,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
page.drawText(SignedNumberToText(Modifier(tulajdonsagok.t_kar)), {
|
||||
x: 176,
|
||||
y: 449,
|
||||
size: fontSizeBase * 2,
|
||||
font: pdfFont,
|
||||
color: rgb(0, 0, 0),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import 'bootstrap/dist/css/bootstrap.css';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
import { getWebInstrumentations, initializeFaro } from '@grafana/faro-web-sdk';
|
||||
|
||||
const faro = window.location.hostname === 'localhost' ? undefined : initializeFaro({
|
||||
url: 'https://faro-collector-prod-eu-west-2.grafana.net/collect/88adcc2543da5af525c451166286f2cc',
|
||||
app: {
|
||||
name: 'kemkas',
|
||||
version: '1.0.0',
|
||||
environment: 'production'
|
||||
},
|
||||
instrumentations: [
|
||||
// Mandatory, overwriting the instrumentations array would cause the default instrumentations to be omitted
|
||||
...getWebInstrumentations(),
|
||||
|
||||
// Initialization of the tracing package.
|
||||
// This packages is optional because it increases the bundle size noticeably. Only add it if you want tracing data.
|
||||
// new TracingInstrumentation(),
|
||||
],
|
||||
});
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById('root') as HTMLElement
|
||||
);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App faro={faro} />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
||||
+1
@@ -0,0 +1 @@
|
||||
/// <reference types="react-scripts" />
|
||||
@@ -0,0 +1,15 @@
|
||||
import { ReportHandler } from 'web-vitals';
|
||||
|
||||
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
||||
@@ -0,0 +1,36 @@
|
||||
const { createProxyMiddleware } = require('http-proxy-middleware');
|
||||
const { env } = require('process');
|
||||
|
||||
const target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :
|
||||
env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:40870';
|
||||
|
||||
const context = [
|
||||
"/weatherforecast",
|
||||
"/_configuration",
|
||||
"/.well-known",
|
||||
"/Identity",
|
||||
"/connect",
|
||||
"/ApplyDatabaseMigrations",
|
||||
"/_framework"
|
||||
];
|
||||
|
||||
const onError = (err, req, resp, target) => {
|
||||
console.error(`${err.message}`);
|
||||
}
|
||||
|
||||
module.exports = function (app) {
|
||||
const appProxy = createProxyMiddleware(context, {
|
||||
target: target,
|
||||
// Handle errors to prevent the proxy middleware from crashing when
|
||||
// the ASP NET Core webserver is unavailable
|
||||
onError: onError,
|
||||
secure: false,
|
||||
// Uncomment this line to add support for proxying websockets
|
||||
//ws: true,
|
||||
headers: {
|
||||
Connection: 'Keep-Alive'
|
||||
}
|
||||
});
|
||||
|
||||
app.use(appProxy);
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
const localStorageMock = {
|
||||
getItem: jest.fn(),
|
||||
setItem: jest.fn(),
|
||||
removeItem: jest.fn(),
|
||||
clear: jest.fn(),
|
||||
length: 0,
|
||||
key: jest.fn()
|
||||
};
|
||||
global.localStorage = localStorageMock;
|
||||
|
||||
// Mock the request issued by the react app to get the client configuration parameters.
|
||||
window.fetch = () => {
|
||||
return Promise.resolve(
|
||||
{
|
||||
ok: true,
|
||||
json: () => Promise.resolve({
|
||||
"authority": "https://localhost:7251",
|
||||
"client_id": "Kemkas.Web",
|
||||
"redirect_uri": "https://localhost:7251/authentication/login-callback",
|
||||
"post_logout_redirect_uri": "https://localhost:7251/authentication/logout-callback",
|
||||
"response_type": "id_token token",
|
||||
"scope": "Kemkas.WebAPI openid profile"
|
||||
})
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
export function arraySetN<T>(array: T[], n: number, elem: T): T[] {
|
||||
if (array.length < n || n < 0) {
|
||||
return array
|
||||
}
|
||||
return [...array.slice(0, n), elem, ...array.slice(n+1)]
|
||||
}
|
||||
Reference in New Issue
Block a user