feat: multiclassing almost works in 2e

This commit is contained in:
2024-02-13 23:57:42 +01:00
parent 2fe8fb05e7
commit 35b12524ab
11 changed files with 252 additions and 85 deletions
@@ -3,7 +3,8 @@ import {Karakter2E} from "../domain-models/karakter2E";
import {SignedNumberToText} from "../../shared/components/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";
import {MultiClassTamadasBonusz} from "../domain-models/tamadas_bonusz";
import {Osztaly2E} from "../domain-models/osztaly2E";
function MentoNovekedes(props : {tipus: MentoTipus, ujMentok: Mentok, regiMentok: Mentok}) {
const {tipus, ujMentok, regiMentok} = props
@@ -28,16 +29,17 @@ function UjMento(props : {tipus: MentoTipus, ujMentok: Mentok, regiMentok: Mento
}
function BasicNewLevel(props: {
karakter: Pick<Karakter2E, 'osztaly' | 'tulajdonsagok' | 'szintlepesek'>
karakter: Pick<Karakter2E, 'tulajdonsagok' | 'szintlepesek'>
szint: number
osztaly: Osztaly2E
changeRolledHP: (hp: number) => void,
}) {
const {karakter, szint, changeRolledHP} = props
const regiMentok = MentokTotal({...karakter, szint: szint - 1})
const ujMentok = MentokTotal({...karakter, szint: szint})
const {karakter, szint, osztaly, changeRolledHP} = props
const regiMentok = MentokTotal({...karakter, szintlepesek: karakter.szintlepesek.slice(0, szint - 1)})
const ujMentok = MentokTotal({...karakter, szintlepesek: karakter.szintlepesek.slice(0, szint)})
const regiTB = TamadasBonusz(karakter.osztaly, szint-1)
const ujTB = TamadasBonusz(karakter.osztaly, szint)
const regiTB = MultiClassTamadasBonusz(karakter.szintlepesek.slice(0, szint-1))
const ujTB = MultiClassTamadasBonusz(karakter.szintlepesek.slice(0, szint))
if (regiTB.length < ujTB.length) {
regiTB.push(0)
}
@@ -48,7 +50,7 @@ function BasicNewLevel(props: {
<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>
<label className='col-sm-6 col-8 col-form-label'>Plusz dobott HP (d{BaseHP(osztaly)}){' '}</label>
<div className='col-sm-2 col'>
<input
className='form-control'
@@ -71,7 +73,7 @@ function BasicNewLevel(props: {
<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, szintlepesek: karakter.szintlepesek.slice(0, szint-1)})}</span>
<span className='col col-form-label'>{HP({...karakter, szintlepesek: karakter.szintlepesek.slice(0, szint)})}</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>
@@ -1,5 +1,5 @@
import React from "react";
import {Karakter2E} from "../domain-models/karakter2E";
import {ChangeOsztalyAtSzint, Karakter2E} from "../domain-models/karakter2E";
import BasicNewLevel from "./BasicNewLevel";
import TulajdonsagNoveles from "./TulajdonsagNoveles";
import {Tulajdonsag2E, TulajdonsagokTotal} from "../domain-models/tulajdonsag2E";
@@ -7,24 +7,31 @@ import {arraySetN} from "../../util";
import {Osztaly2E} from "../domain-models/osztaly2E";
import KalozKritikus from "./KalozKritikus";
import HarcosFegyverSpecializacio from "./HarcosFegyverSpec";
import {BasicOsztalySelector2E} from "./OsztalySelector2E";
function LevelUp(props: {
szint: number,
osztaly: Osztaly2E,
karakter: Karakter2E,
changeTulajdonsagNoveles: (t: Tulajdonsag2E) => void,
changeRolledHP: (rolledHP: number) => void,
changeHarcosSpec: (spec: string) => void,
changeKalozKritikus: (krit: string) => void,
changeOsztaly: (osztaly: Osztaly2E) => void
}) {
const {
szint,
osztaly,
karakter,
changeTulajdonsagNoveles,
changeRolledHP,
changeHarcosSpec,
changeKalozKritikus,
changeOsztaly
} = props
const harcosSzint = karakter.szintlepesek.filter(x => x.osztaly === Osztaly2E.Harcos).length
const kalozSzint = karakter.szintlepesek.filter(x => x.osztaly === Osztaly2E.Tengeresz).length
const specialization = karakter.szintlepesek[szint-1].harcosFegyver
const krit = karakter.szintlepesek[szint-1].kalozKritikus
@@ -32,6 +39,7 @@ function LevelUp(props: {
<div className='row mt-3'>
<h5 className='col align-self-center'>{szint}. Szint</h5>
</div>
<BasicOsztalySelector2E faj={karakter.faj} osztaly={osztaly} changeOsztaly={changeOsztaly} />
{szint % 4 === 0
&& <TulajdonsagNoveles
tulajdonsagok={karakter.tulajdonsagok}
@@ -41,22 +49,23 @@ function LevelUp(props: {
<BasicNewLevel
szint={szint}
karakter={karakter}
osztaly={osztaly}
changeRolledHP={changeRolledHP}
/>
{karakter.osztaly === Osztaly2E.Harcos && szint % 2 === 1 &&
{osztaly === Osztaly2E.Harcos && harcosSzint % 2 === 1 &&
<HarcosFegyverSpecializacio
specialization={specialization!}
existingSpecializations={karakter.szintlepesek.map(x => x.harcosFegyver)}
changeSpecialization={changeHarcosSpec}
szint={szint}
szint={harcosSzint}
/>
}
{karakter.osztaly === Osztaly2E.Tengeresz && szint % 3 === 0 && !!krit &&
{osztaly === Osztaly2E.Tengeresz && kalozSzint % 3 === 0 && !!krit &&
<KalozKritikus
kritFegyverId={krit}
existingKrits={karakter.szintlepesek.map(x => x.kalozKritikus)}
changeKrit={changeKalozKritikus}
szint={szint}
szint={kalozSzint}
/>
}
</div>
@@ -65,10 +74,10 @@ function LevelUp(props: {
export function LevelUps(props: {karakter: Karakter2E, changeKarakter: (inputs: Karakter2E) => void}){
const {karakter, changeKarakter} = props;
const tulajdonsagokAtSzint = (szint: number) => TulajdonsagokTotal({...karakter, szintlepesek: karakter.szintlepesek.slice(0, szint - 1)})
const tulajdonsagokAtSzint = (szint: number) => TulajdonsagokTotal({...karakter, szintlepesek: karakter.szintlepesek.slice(0, szint)})
const changeRolledHPAtSzint = (szint: number) => (newHProll: number) => {
changeKarakter({...karakter, szintlepesek: arraySetN(karakter.szintlepesek, szint-2, {...karakter.szintlepesek[szint-2], HProll: newHProll})})
changeKarakter({...karakter, szintlepesek: arraySetN(karakter.szintlepesek, szint-1, {...karakter.szintlepesek[szint-1], HProll: newHProll})})
console.log(karakter)
}
const changeTulajdonsagNovelesAtSzint = (szint: number) => {
@@ -113,11 +122,13 @@ export function LevelUps(props: {karakter: Karakter2E, changeKarakter: (inputs:
<LevelUp
key={`level-up-${szint}`}
szint={szint}
karakter={{...karakter, tulajdonsagok: tulajdonsagokAtSzint(szint)}}
osztaly={karakter.szintlepesek[szint-1].osztaly}
karakter={{...karakter, szintlepesek: karakter.szintlepesek.slice(0, szint) ,tulajdonsagok: tulajdonsagokAtSzint(szint)}}
changeTulajdonsagNoveles={changeTulajdonsagNovelesAtSzint(szint)}
changeRolledHP={changeRolledHPAtSzint(szint)}
changeHarcosSpec={changeHarcosSpecializacioAtSzint(szint)}
changeKalozKritikus={changeKalozKritikusAtSzint(szint)}
changeOsztaly={(o) => changeKarakter(ChangeOsztalyAtSzint(karakter, o, szint))}
/>
)}
</>
@@ -8,21 +8,16 @@ import {
} from "../domain-models/osztaly2E";
import {Faj2E, SzintKorlatokFajokra} from "../domain-models/faj2E";
function OsztalySelector2E(props: {
currentFaj: Faj2E,
currentOsztaly: Osztaly2E,
changeOsztaly: (newOsztaly: Osztaly2E) => void
}) {
const {currentFaj, currentOsztaly, changeOsztaly} = props;
export function BasicOsztalySelector2E(props: {faj: Faj2E, osztaly: Osztaly2E, changeOsztaly: (osztaly: Osztaly2E) => void}) {
const {faj, osztaly, 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}
<select className="col form-select" value={osztaly}
onChange={(e) => changeOsztaly(e.target.value as Osztaly2E)}>
<optgroup label='Harcos'>
<option value={Osztaly2E.Harcos}>{OsztalyLabel(Osztaly2E.Harcos)}</option>
{SzintKorlatokFajokra(currentFaj)[Osztaly2E.Amazon] > 0 && (
{SzintKorlatokFajokra(faj)[Osztaly2E.Amazon] > 0 && (
<option value={Osztaly2E.Amazon}>{OsztalyLabel(Osztaly2E.Amazon)}</option>)}
<option value={Osztaly2E.Barbar}>{OsztalyLabel(Osztaly2E.Barbar)}</option>
<option value={Osztaly2E.Ijasz}>{OsztalyLabel(Osztaly2E.Ijasz)}</option>
@@ -41,6 +36,18 @@ function OsztalySelector2E(props: {
</optgroup>
</select>
</div>
</>
}
function OsztalySelector2E(props: {
currentFaj: Faj2E,
currentOsztaly: Osztaly2E,
changeOsztaly: (newOsztaly: Osztaly2E) => void
}) {
const {currentFaj, currentOsztaly, changeOsztaly} = props;
return <>
<BasicOsztalySelector2E faj={currentFaj} osztaly={currentOsztaly} changeOsztaly={changeOsztaly} />
<div className='row m-2'>
<label className='col-md-2 col-sm-3 form-label'></label>
<div className='col'>
@@ -17,7 +17,6 @@ export interface Karakter2E {
jellem: JellemID,
tulajdonsagok: KarakterTulajdonsagok
faj: Faj2E
osztaly: Osztaly2E
kepzettsegek: KepzettsegId[]
tolvajKepzettsegek?: KepzettsegId[]
szint: number,
@@ -31,7 +30,6 @@ export const DefaultKarakter: Karakter2E = {
jellem: 'S',
tulajdonsagok: TulajdonsagDefaults,
faj: Faj2E.Ember,
osztaly: Osztaly2E.Tengeresz,
kepzettsegek: [],
tolvajKepzettsegek: [],
szint: 1,
@@ -42,34 +40,93 @@ export const DefaultKarakter: Karakter2E = {
}]
}
function setOsztalyForSzintLepes(szintlepes: Szintlepes, osztaly: Osztaly2E, szint: number): Szintlepes {
const base : Szintlepes = {
...szintlepes,
function setOsztalyForSzintLepes(szintlepesek: Szintlepes[], osztaly: Osztaly2E, szint: number): Szintlepes[] {
const prev = szintlepesek.slice(0, szint-1)
const current : Szintlepes = {
...szintlepesek[szint-1],
osztaly,
harcosFegyver: undefined,
kalozKritikus: undefined
}
const tail = szintlepesek.slice(szint).map(x => {return {...x}})
if (osztaly === Osztaly2E.Harcos && szint % 2 === 1) {
base.harcosFegyver = AllowedFegyver(Osztaly2E.Harcos)[szint].Id
let harcosSzint = prev.filter(x => x.osztaly === Osztaly2E.Harcos).length
// TODO: only pick specializations from valid levels
const harcosSpecializaciok = szintlepesek
.map(x => x.harcosFegyver)
.filter(x => x != null)
const harcosSpecAtSzint = (hSzint: number): (string | undefined) => {
if (hSzint % 2 === 1) {
const specIndex = (hSzint+1)/2 -1
if (harcosSpecializaciok.length > specIndex ) {
return harcosSpecializaciok[specIndex]
} else {
return AllowedFegyver(Osztaly2E.Harcos)[specIndex].Id
}
}
else {
return undefined
}
}
if (osztaly === Osztaly2E.Tengeresz && szint % 3 === 0) {
base.kalozKritikus = AllowedFegyver(Osztaly2E.Tengeresz)[szint].Id
if (osztaly === Osztaly2E.Harcos) {
harcosSzint += 1
current.harcosFegyver = harcosSpecAtSzint(harcosSzint)
}
for (let i = 0; i < tail.length; i++) {
if (tail[i].osztaly === Osztaly2E.Harcos) {
harcosSzint++
tail[i].harcosFegyver = harcosSpecAtSzint(harcosSzint)
}
}
let kalozSzint = prev.filter(x => x.osztaly === Osztaly2E.Tengeresz).length
const existingKalozKrits = szintlepesek
.map(x => x.kalozKritikus)
.filter(x => x != null)
const kalozKritAtSzint = (kSzint: number): (string | undefined) => {
if (kSzint % 3 === 0) {
const specIndex = kSzint/3 -1
if (existingKalozKrits.length > specIndex ) {
return existingKalozKrits[specIndex]
} else {
return AllowedFegyver(Osztaly2E.Tengeresz)[specIndex].Id
}
}
else {
return undefined
}
}
if (osztaly === Osztaly2E.Tengeresz) {
kalozSzint++
current.kalozKritikus = kalozKritAtSzint(szint)
}
for (let i = 0; i < tail.length; i++) {
if (tail[i].osztaly === Osztaly2E.Tengeresz) {
kalozSzint++
tail[i].kalozKritikus = kalozKritAtSzint(kalozSzint)
}
}
const HD = BaseHP(osztaly)
if (szint === 1) {
base.HProll = HD
current.HProll = HD
} else {
base.HProll = dAny(HD)
console.log(`Level ${szint} HP roll on d${HD} is: ${base.HProll} due to class change`)
current.HProll = dAny(HD)
console.log(`Level ${szint} HP roll on d${HD} is: ${current.HProll} due to class change`)
}
return base
return [...prev, current, ...tail]
}
export function ChangeLvl1Osztaly(karakter: Karakter2E, osztaly: Osztaly2E): Karakter2E {
return {
...karakter,
osztaly,
szintlepesek: karakter.szintlepesek.map((l, idx) => setOsztalyForSzintLepes(l, osztaly, idx +1))
szintlepesek: [{...karakter.szintlepesek[0], osztaly}, ...karakter.szintlepesek.slice(1)]
}
}
export function ChangeOsztalyAtSzint(karakter: Karakter2E, osztaly: Osztaly2E, szint: number): Karakter2E {
return {
...karakter,
szintlepesek: setOsztalyForSzintLepes(karakter.szintlepesek, osztaly, szint)
}
}
@@ -209,12 +209,12 @@ export const Kepzettsegek: Record<KepzettsegId, Kepzettseg> =
(acc: Record<KepzettsegId, Kepzettseg>, k) => { acc[k.Id] = k; return acc; },
{} as Record<KepzettsegId, Kepzettseg>);
export function AvailableKezpettsegList(osztaly: Osztaly2E): Kepzettseg[] {
return KepzettsegLista.filter(k => k.Osztalyok == null || k.Osztalyok.includes(osztaly))
export function AvailableKezpettsegList(...osztalyok: Osztaly2E[]): Kepzettseg[] {
return KepzettsegLista.filter(k => k.Osztalyok == null || k.Osztalyok.some(o => osztalyok.includes(o)))
}
export function GetNumberOfKepzettsegek(t_int: number, faj: Faj2E, max: number = 11) {
//max = 3 + 1 + 3 + 4 // 3 base, 1 human, 3 from max ability modifier, 4 from Thief
//max = 3 + 1 + 3 + 5 = 12 // 3 base, 1 human, 3 from max ability modifier, 5 from Thief at 9th level
let numberOfKepzettseg = 3 + Modifier(t_int) + (faj === Faj2E.Ember ? 1 : 0)
if (numberOfKepzettseg < 1) {
@@ -228,18 +228,20 @@ export function GetNumberOfKepzettsegek(t_int: number, faj: Faj2E, max: number =
return numberOfKepzettseg;
}
export function SetDefaultTolvajKepzettsegek(karakter: Pick<Karakter2E, 'osztaly' | 'szintlepesek' | 'tolvajKepzettsegek'>, changeTolvajKepzettsegek: (tolvajKepzettsegek?: KepzettsegId[]) => void) {
if (karakter.osztaly !== Osztaly2E.Tolvaj && karakter.tolvajKepzettsegek != null) {
export function SetDefaultTolvajKepzettsegek(karakter: Pick<Karakter2E, 'szintlepesek' | 'tolvajKepzettsegek'>, changeTolvajKepzettsegek: (tolvajKepzettsegek?: KepzettsegId[]) => void) {
const hasTolvajSzint = karakter.szintlepesek.some(szint => szint.osztaly === Osztaly2E.Tolvaj)
if (!hasTolvajSzint && karakter.tolvajKepzettsegek != null) {
changeTolvajKepzettsegek(undefined)
}
if (karakter.osztaly === Osztaly2E.Tolvaj && (karakter.tolvajKepzettsegek == null || karakter.tolvajKepzettsegek.length === 0)) {
if (hasTolvajSzint && (karakter.tolvajKepzettsegek == null || karakter.tolvajKepzettsegek.length === 0)) {
const tolvajKepzettsegek = TolvajKepzettsegList.slice(0, 4).map(x => x.Id)
changeTolvajKepzettsegek(tolvajKepzettsegek)
}
}
export function GetKepzettsegListaN(karakter: Pick<Karakter2E, 'osztaly' | 'faj' | 'kepzettsegek' | 'tolvajKepzettsegek'>) {
const availableKepzettsegList = AvailableKezpettsegList(karakter.osztaly)
export function GetKepzettsegListaN(karakter: Pick<Karakter2E, 'szintlepesek' | 'faj' | 'kepzettsegek' | 'tolvajKepzettsegek'>) {
const osztalyok = new Set(karakter.szintlepesek.map(x => x.osztaly))
const availableKepzettsegList = AvailableKezpettsegList(...osztalyok)
return (n: number): Kepzettseg[] => {
let available = [...availableKepzettsegList]
if (n === 0) {
@@ -249,7 +251,8 @@ export function GetKepzettsegListaN(karakter: Pick<Karakter2E, 'osztaly' | 'faj'
if (karakter.faj === Faj2E.Nomad) {
return [Kepzettsegek.k_lovaglas]
}
if (karakter.faj === Faj2E.Birodalmi && karakter.osztaly !== Osztaly2E.Tolvaj) {
// TODO birodalmi tolvaj, tolvajképzettségek!
if (karakter.faj === Faj2E.Birodalmi) {
return [Kepzettsegek.k_alkimia, Kepzettsegek.k_meregkeveres, Kepzettsegek.k_okkultizmus]
}
if (karakter.faj === Faj2E.Torpe) {
@@ -258,21 +261,28 @@ export function GetKepzettsegListaN(karakter: Pick<Karakter2E, 'osztaly' | 'faj'
if (karakter.faj === Faj2E.Elf || karakter.faj === Faj2E.Felelf) {
return [Kepzettsegek.k_vadonjaras]
}
if (karakter.osztaly === Osztaly2E.Druida || karakter.osztaly === Osztaly2E.Vandor) {
if (osztalyok.has(Osztaly2E.Druida) || osztalyok.has(Osztaly2E.Vandor)) {
return [Kepzettsegek.k_vadonjaras]
}
if (karakter.osztaly === Osztaly2E.Dalnok) {
if (osztalyok.has(Osztaly2E.Dalnok)) {
return [Kepzettsegek.k_eloadas]
}
}
if (n === 1) {
if (karakter.osztaly === Osztaly2E.Dalnok
&& [Faj2E.Eszaki, Faj2E.Nomad, Faj2E.Birodalmi, Faj2E.Torpe, Faj2E.Elf, Faj2E.Felelf].includes(karakter.faj)) {
if ((osztalyok.has(Osztaly2E.Vandor) || osztalyok.has(Osztaly2E.Druida))
&& karakter.kepzettsegek[0] !== Kepzettsegek.k_vadonjaras.Id) {
return [Kepzettsegek.k_vadonjaras]
}
if (osztalyok.has(Osztaly2E.Dalnok)
&& karakter.kepzettsegek[0] !== Kepzettsegek.k_eloadas.Id) {
return [Kepzettsegek.k_eloadas]
}
if ([Osztaly2E.Druida, Osztaly2E.Vandor].includes(karakter.osztaly)
&& [Faj2E.Eszaki, Faj2E.Nomad, Faj2E.Birodalmi, Faj2E.Torpe].includes(karakter.faj)) {
return [Kepzettsegek.k_vadonjaras]
}
if (n === 2) { // maybe write a better abstraction?
if (osztalyok.has(Osztaly2E.Dalnok)
&& karakter.kepzettsegek[0] !== Kepzettsegek.k_eloadas.Id
&& karakter.kepzettsegek[1] !== Kepzettsegek.k_eloadas.Id) {
return [Kepzettsegek.k_eloadas]
}
}
const kepzettsegekWithoutN = [...karakter.kepzettsegek.slice(0, n), ...karakter.kepzettsegek.slice(n + 1)]
@@ -280,8 +290,9 @@ export function GetKepzettsegListaN(karakter: Pick<Karakter2E, 'osztaly' | 'faj'
}
}
export function SetDefaultKepzettsegek(karakter: Pick<Karakter2E, 'osztaly' | 'faj' | 'tulajdonsagok' | 'kepzettsegek' | 'tolvajKepzettsegek'>, changeKepzettsegek: (k: KepzettsegId[]) => void) {
const availableKepzettsegList = AvailableKezpettsegList(karakter.osztaly)
export function SetDefaultKepzettsegek(karakter: Pick<Karakter2E, 'szintlepesek' | 'faj' | 'tulajdonsagok' | 'kepzettsegek' | 'tolvajKepzettsegek'>, changeKepzettsegek: (k: KepzettsegId[]) => void) {
const osztalyok = karakter.szintlepesek.map(x => x.osztaly)
const availableKepzettsegList = AvailableKezpettsegList(...osztalyok)
const numberOfKepzettsegek = GetNumberOfKepzettsegek(karakter.tulajdonsagok.t_int, karakter.faj, availableKepzettsegList.length)
let kepzettsegek = [...karakter.kepzettsegek]
@@ -14,7 +14,7 @@ export interface MasodlagosErtekekView {
Mentok: Mentok
}
export type KarakterpickForMasodlagosErtekek = Pick<Karakter2E, 'osztaly' | 'tulajdonsagok' | 'szint' | 'szintlepesek' | 'faj' | 'felszereles'>
export type KarakterpickForMasodlagosErtekek = Pick<Karakter2E, 'tulajdonsagok' | 'szint' | 'szintlepesek' | 'faj' | 'felszereles'>
export function BaseHP(osztaly: Osztaly2E) {
let base = 4;
@@ -45,7 +45,7 @@ export function BaseHP(osztaly: Osztaly2E) {
return base
}
export function HP(karakter: Pick<Karakter2E, 'osztaly' | 'tulajdonsagok' | 'szintlepesek'>): number {
export function HP(karakter: Pick<Karakter2E, 'tulajdonsagok' | 'szintlepesek'>): number {
const egeszsegModifier = Modifier(karakter.tulajdonsagok.t_egs)
return karakter.szintlepesek
// https://lfg.hu/forum/topic/15079-kard-es-magia/page/219/#comment-2218333
@@ -53,7 +53,8 @@ export function HP(karakter: Pick<Karakter2E, 'osztaly' | 'tulajdonsagok' | 'szi
.reduce((sum, val) => sum + val, 0)
}
export function VO(karakter: Pick<Karakter2E, 'tulajdonsagok' | 'faj' | 'osztaly' | 'szint' | 'felszereles'>): number {
export function VO(karakter: Pick<Karakter2E, 'tulajdonsagok' | 'faj' | 'szintlepesek' | 'szint' | 'felszereles'>): number {
const osztalyok = new Set(karakter.szintlepesek.map(x => x.osztaly))
const pancel = GetPancel(karakter.felszereles.pancelID)
const pancelVO = pancel?.VO ?? 0
const pajzsVO = GetPajzs(karakter.felszereles.pajzsID)?.VO ?? 0
@@ -62,14 +63,16 @@ export function VO(karakter: Pick<Karakter2E, 'tulajdonsagok' | 'faj' | 'osztaly
if (pancel) {
abilityVO = Math.min(MaxAbilityVO(pancel.Type), abilityVO)
}
if (karakter.osztaly === Osztaly2E.Tengeresz) {
vo += Math.floor(karakter.szint / 3)
if (osztalyok.has(Osztaly2E.Tengeresz)) {
const kalozSzintek = karakter.szintlepesek.filter(x => x.osztaly === Osztaly2E.Tengeresz).length
vo += Math.floor(kalozSzintek / 3)
}
if (karakter.osztaly === Osztaly2E.Amazon) {
if (osztalyok.has(Osztaly2E.Amazon)) {
if (karakter.tulajdonsagok.t_kar > karakter.tulajdonsagok.t_ugy) {
abilityVO = Modifier(karakter.tulajdonsagok.t_kar)
}
vo += Math.floor(karakter.szint / 2)
const amazonSzintek = karakter.szintlepesek.filter(x => x.osztaly === Osztaly2E.Amazon).length
vo += Math.floor(amazonSzintek / 2)
}
if (karakter.faj === Faj2E.Felszerzet || karakter.faj === Faj2E.Gnom){
vo += 1
@@ -1,6 +1,7 @@
import {Osztaly2E} from "./osztaly2E";
import {Karakter2E} from "./karakter2E";
import {KarakterTulajdonsagok, TulajdonsagModosito} from "./tulajdonsag2E";
import {Szintlepes} from "./szintlepes";
export interface Mentok {
kitartas: number
@@ -73,8 +74,26 @@ export function MentoModositok(tulajdonsagModositok: KarakterTulajdonsagok) {
}
}
export function MentokTotal(karakter: Pick<Karakter2E, 'osztaly' | 'szint' | 'tulajdonsagok'>) {
const alap = MentokAlap(karakter.osztaly, karakter.szint)
export function MultiClassMentokAlap(szintlepesek: Szintlepes[]) : Mentok {
const osztalyok = new Set(szintlepesek.map(x => x.osztaly))
let mentok = {
kitartas: 0,
reflex: 0,
akaratero: 0
}
for (const osztaly of osztalyok) {
const szint = szintlepesek.filter(x => x.osztaly === osztaly).length
const uj_mentok = MentokAlap(osztaly, szint)
mentok.akaratero += uj_mentok.akaratero
mentok.reflex += uj_mentok.reflex
mentok.kitartas += uj_mentok.kitartas
}
return mentok
}
export function MentokTotal(karakter: Pick<Karakter2E, 'szintlepesek' | 'tulajdonsagok'>) {
const alap = MultiClassMentokAlap(karakter.szintlepesek)
const modositok = MentoModositok(TulajdonsagModosito(karakter.tulajdonsagok))
return {
kitartas: alap.kitartas + modositok.kitartas,
@@ -20,14 +20,15 @@ export function PickableSpecializationFilter(existingSpecilizations: (string | u
}
export function LevelUp(karakter: Karakter2E, changeKarakter: (input: Karakter2E) => void) {
const osztaly = karakter.szintlepesek[0].osztaly
const tulajdonsagokTotal = TulajdonsagokTotal(karakter)
const szint = karakter.szint + 1
const dice = BaseHP(karakter.osztaly)
const dice = BaseHP(osztaly)
const roll = dAny(dice)
console.log(`Level ${szint} HP roll on d${dice} is: ${roll}`)
const szintlepes: Szintlepes = {
osztaly: karakter.osztaly,
osztaly: osztaly,
HProll: roll
}
@@ -39,14 +40,24 @@ export function LevelUp(karakter: Karakter2E, changeKarakter: (input: Karakter2E
}
}
}
if(karakter.osztaly === Osztaly2E.Harcos && szint % 2 === 1) {
const harcosSpecializaciok = karakter.szintlepesek.map(x => x.harcosFegyver)
szintlepes.harcosFegyver = AllowedFegyver(Osztaly2E.Harcos).filter(PickableSpecializationFilter(harcosSpecializaciok, karakter.szint))[0].Id
if(osztaly === Osztaly2E.Harcos) {
const harcosSzint = karakter.szintlepesek.filter(x => x.osztaly === Osztaly2E.Harcos).length + 1
if (harcosSzint % 2 === 1) {
const harcosSpecializaciok = karakter.szintlepesek.map(x => x.harcosFegyver)
let specializationFilter = PickableSpecializationFilter(harcosSpecializaciok, harcosSzint)
szintlepes.harcosFegyver = AllowedFegyver(Osztaly2E.Harcos).filter(specializationFilter)[0].Id
}
}
if(karakter.osztaly === Osztaly2E.Tengeresz && szint % 3 === 0) {
let kalozKritikus = karakter.szintlepesek.map(x => x.kalozKritikus)
szintlepes.kalozKritikus = AllowedFegyver(Osztaly2E.Tengeresz).filter(PickableSpecializationFilter(kalozKritikus, szint))[0].Id
if(osztaly === Osztaly2E.Tengeresz) {
const kalozSzint = karakter.szintlepesek.filter(x => x.osztaly === Osztaly2E.Tengeresz).length + 1
if (kalozSzint % 3 === 0) {
let kalozKritikus = karakter.szintlepesek.map(x => x.kalozKritikus)
let specializationFilter = PickableSpecializationFilter(kalozKritikus, kalozSzint)
szintlepes.kalozKritikus = AllowedFegyver(Osztaly2E.Tengeresz).filter(specializationFilter)[0].Id
}
}
console.log(`picked harcos specializacio ${szintlepes.harcosFegyver}`)
console.log(`picked kaloz krit ${szintlepes.kalozKritikus}`)
changeKarakter({...karakter, szint, szintlepesek: [...karakter.szintlepesek, szintlepes]})
}
@@ -1,6 +1,7 @@
import {Osztaly2E} from "./osztaly2E";
import {Karakter2E} from "./karakter2E";
import {Modifier} from "./tulajdonsag2E";
import {Szintlepes} from "./szintlepes";
/// Finally second edition doesn't mess with the extra attack of high level clerics rouges and wizards!
function ExtraAttack(attack: number): number[] {
@@ -10,6 +11,31 @@ function ExtraAttack(attack: number): number[] {
return [Math.min(attack, 10), ...ExtraAttack(attack - 5)]
}
export function TamadasBonuszBase(osztaly: Osztaly2E, szint: number = 1) : number {
let base = 0
switch (osztaly){
case Osztaly2E.Barbar:
case Osztaly2E.Amazon:
case Osztaly2E.Ijasz:
case Osztaly2E.Tengeresz:
case Osztaly2E.Harcos:
case Osztaly2E.Vandor:
base = szint;
break;
case Osztaly2E.Pap:
case Osztaly2E.Tolvaj:
case Osztaly2E.Dalnok:
case Osztaly2E.Druida:
base = Math.floor(szint * 2 / 3);
break;
case Osztaly2E.Varazslo:
case Osztaly2E.Illuzionista:
base = Math.floor(szint / 2);
break;
}
return base
}
export function TamadasBonusz(osztaly: Osztaly2E, szint: number = 1) : number[] {
let base = 0
switch (osztaly){
@@ -35,12 +61,23 @@ export function TamadasBonusz(osztaly: Osztaly2E, szint: number = 1) : number[]
return ExtraAttack(base)
}
export function KozelharciTB(karakter : Pick<Karakter2E, 'szint' | 'tulajdonsagok' | 'osztaly'>): number[] {
const base = TamadasBonusz(karakter.osztaly, karakter.szint);
export function MultiClassTamadasBonusz(szintlepesek: Szintlepes[]) : number[]{
const osztalyok = new Set(szintlepesek.map(x => x.osztaly))
let TBB = 0
for (const osztaly of osztalyok) {
const szint = szintlepesek.filter(x => x.osztaly === osztaly).length
TBB += TamadasBonuszBase(osztaly, szint)
}
return ExtraAttack(TBB)
}
export function KozelharciTB(karakter : Pick<Karakter2E, 'szintlepesek' | 'tulajdonsagok'>): number[] {
const base = MultiClassTamadasBonusz(karakter.szintlepesek);
let modifier = Modifier(karakter.tulajdonsagok.t_ero)
return base.map(v => v + modifier)
}
export function CelzoTB(karakter : Pick<Karakter2E, 'szint' | 'tulajdonsagok' | 'osztaly'>): number[] {
let base = TamadasBonusz(karakter.osztaly, karakter.szint)
export function CelzoTB(karakter : Pick<Karakter2E, 'szintlepesek' | 'tulajdonsagok'>): number[] {
let base = MultiClassTamadasBonusz(karakter.szintlepesek)
return base.map(v => v + Modifier(karakter.tulajdonsagok.t_ugy))
}
@@ -103,7 +103,7 @@ function CreateCharacter2E(props: {}) {
</div>
<OsztalySelector2E
currentFaj={karakter.faj}
currentOsztaly={karakter.osztaly}
currentOsztaly={karakter.szintlepesek[0].osztaly}
changeOsztaly={o => setKarakter(ChangeLvl1Osztaly(karakter, o))}
/>
{karakter.szintlepesek[0].osztaly === Osztaly2E.Harcos &&
+10 -1
View File
@@ -13,12 +13,21 @@
## Features
- multiclass characters
- 2e -ben félig működik
- druidáknál tiltani kell
- PDF-ben varazshasznalok
- tolvaj 9ik szintű képessége
## Epics
- Backend
- Varazslatok
- Felszerelés
- KéM 2.0-ra felkészülés
- 1e-ben fel van már véve az adat. Gergő neki veselkedik.
- 2e-ben teljesen hiányzik
- KéM 2e
- frontend oldalon úgy, ahogy megvan
- PDF hiányzik
- backend hiányzik
- Klikkelésre dobás