ci: split repo: make this repo frontend only again

This commit is contained in:
2024-03-09 00:08:09 +01:00
parent 5f56f34b4e
commit b132a5801b
308 changed files with 9 additions and 43867 deletions
@@ -0,0 +1,89 @@
import {KarakterPdfView, KepzettsegPdfView} from "./karakter_pdf_view";
import {PDFDocument, rgb} from "pdf-lib";
import fontkit from '@pdf-lib/fontkit'
import {SignedNumberToText} from "../../shared/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('/pdfs/km_karakterlap_hysteria_1.2.pdf').then(res => res.arrayBuffer())
const pdfDoc = await PDFDocument.load(existingPdfBytes)
pdfDoc.registerFontkit(fontkit)
const fontBytes = await fetch('/fonts/Merienda-Regular.ttf').then(res => res.arrayBuffer())
const pdfFont = await pdfDoc.embedFont(fontBytes)
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('/fonts/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 "../../shared/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,157 @@
import {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 "../../shared/components/Helpers";
import {OsztalySkillsTordelt} from "./osztaly_skills";
import {
KarakterTulajdonsagok,
Modifier,
TulajdonsagModosito
} from "../domain-models/tulajdonsag";
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 "../../shared/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 "../../shared/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 {SignedNumberToText} from "../../shared/components/Helpers";
import {KarakterTulajdonsagok, Modifier} from "../domain-models/tulajdonsag";
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),
})
}