mirror of
https://github.com/morbalint/kemkas.git
synced 2026-07-18 03:13:46 +00:00
ci: split repo: make this repo frontend only again
This commit is contained in:
@@ -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),
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user