diff --git a/src/assets/combattechniques.json b/src/assets/combattechniques.json new file mode 100644 index 0000000..e69de29 diff --git a/src/assets/improvementcosttable.json b/src/assets/improvementcosttable.json new file mode 100644 index 0000000..9aab998 --- /dev/null +++ b/src/assets/improvementcosttable.json @@ -0,0 +1,154 @@ +{ + "steigerungsfaktoren": [ + { + "aktivierung": "0", + "faktoren": { + "A": 1, + "B": 2, + "C": 3, + "D": 4, + "E": null + } + }, + { + "aktivierung": "1-12", + "faktoren": { + "A": 1, + "B": 2, + "C": 3, + "D": 4, + "E": 15 + } + }, + { + "aktivierung": "13", + "faktoren": { + "A": 2, + "B": 4, + "C": 6, + "D": 8, + "E": 15 + } + }, + { + "aktivierung": "14", + "faktoren": { + "A": 3, + "B": 6, + "C": 9, + "D": 12, + "E": 15 + } + }, + { + "aktivierung": "15", + "faktoren": { + "A": 4, + "B": 8, + "C": 12, + "D": 16, + "E": 30 + } + }, + { + "aktivierung": "16", + "faktoren": { + "A": 5, + "B": 10, + "C": 15, + "D": 20, + "E": 45 + } + }, + { + "aktivierung": "17", + "faktoren": { + "A": 6, + "B": 12, + "C": 18, + "D": 24, + "E": 60 + } + }, + { + "aktivierung": "18", + "faktoren": { + "A": 7, + "B": 14, + "C": 21, + "D": 28, + "E": 75 + } + }, + { + "aktivierung": "19", + "faktoren": { + "A": 8, + "B": 16, + "C": 24, + "D": 32, + "E": 90 + } + }, + { + "aktivierung": "20", + "faktoren": { + "A": 9, + "B": 18, + "C": 27, + "D": 36, + "E": 105 + } + }, + { + "aktivierung": "21", + "faktoren": { + "A": 10, + "B": 20, + "C": 30, + "D": 40, + "E": 120 + } + }, + { + "aktivierung": "22", + "faktoren": { + "A": 11, + "B": 22, + "C": 33, + "D": 44, + "E": 135 + } + }, + { + "aktivierung": "23", + "faktoren": { + "A": 12, + "B": 24, + "C": 36, + "D": 48, + "E": 150 + } + }, + { + "aktivierung": "24", + "faktoren": { + "A": 13, + "B": 26, + "C": 39, + "D": 52, + "E": 165 + } + }, + { + "aktivierung": "25", + "faktoren": { + "A": 14, + "B": 28, + "C": 42, + "D": 56, + "E": 180 + } + } + ] +} diff --git a/src/assets/skills.json b/src/assets/skills.json new file mode 100644 index 0000000..e69de29 diff --git a/src/classes/Base.ts b/src/classes/Base.ts new file mode 100644 index 0000000..d137585 --- /dev/null +++ b/src/classes/Base.ts @@ -0,0 +1,5 @@ +export default class Base { +constructor() { +} + +} diff --git a/src/classes/CharacterSheet.ts b/src/classes/CharacterSheet.ts new file mode 100644 index 0000000..08254a0 --- /dev/null +++ b/src/classes/CharacterSheet.ts @@ -0,0 +1,88 @@ +import type {DSAAttributes, DSAExperienceLevel, DSAPersonalData, DSAStats} from "../types/baseCharacter.ts"; +import type {DSACalculatedValue, DSAImprovements} from "../types/baseDSA.ts"; +import type {DSABaseEquiment} from "../types/baseEquiment.ts"; +import type {DSAArmor, DSAMeleeWeapon, DSARangedWeapon, DSAShieldParryWeapon} from "../types/equiment.ts"; +import type {DSASpell} from "../types/character.ts"; +import Skill from "./Skill.ts"; + +// TODO +// === LOGIC === +// Skillpoint <-> QualityLevel + +export default class CharacterSheet extends Skill { + public id: string + + personalData: DSAPersonalData + attributes: DSAAttributes + stats: DSAStats + fatePoints: DSACalculatedValue; + experienceLevel: DSAExperienceLevel + advantanges: string[] // TODO + disadvantanges: string[] // TODO + generalSpecialAbilities: string[] // TODO + + skills: string[] // TODO: {physical, social, nature, knowledge, craft} generated by GPT + attributeModifiers: string[] + languages: string[] + scripts: string[] + + combatTechniques: string[] // TODO + combatSpecialAbilities: string[] // TODO + + public inventory: { + closeCombatWeapons: DSAMeleeWeapon[] // TODO + rangedWeapons: DSARangedWeapon[] // TODO + armor: DSAArmor[] // TODO + shieldParryWeapon: DSAShieldParryWeapon[] // TODO + belongings: DSABaseEquiment[] + totalWeight: number // TODO Calculated + carryingCapacity: number // TODO Calculated + purse: { + ducats: number + silverthalers: number + halers: number + kreutzers: number + } + } + + public animal?: { + name: string + sizeCategory: 'winzig' | 'klein' | 'mittel' | 'groß' | 'riesig' + type: string + stats: DSAStats + attributes: DSAAttributes + attack: { + attack: number + defence: number + damagePoints: number + armor: number + } + actions: string[] + specialAbilities: string[] + image?: string + } + + public spellsAndRituals?: { // TODO + properties: string[] + primaryAttribute: string[] + tradition: string[] + magicalSpecialAbilities: string[] + cantrips: string[] + spells?: DSASpell[] + } + + public liturgicalChantsAndCeremonies?: { // TODO + aspects: string[] + primaryAttribute: string[] + tradition: string[] + blessedSpecialAbilities: string[] + blessings: string[] + spells?: DSASpell[] + } + + constructor(name: string) { + super() + this.id = crypto.randomUUID() + this.personalData.name = name + } +} diff --git a/src/classes/Skill.ts b/src/classes/Skill.ts new file mode 100644 index 0000000..59df62f --- /dev/null +++ b/src/classes/Skill.ts @@ -0,0 +1,25 @@ +import type {DSAAttributes} from "../types/baseCharacter.ts"; +import type {DSAImprovements} from "../types/baseDSA.ts"; + +export default class Skill{ + skillName: string + attributes: [keyof DSAAttributes, keyof DSAAttributes, keyof DSAAttributes] + encumbrance: "YES" | "NO" | "MAYBE" + improvement: DSAImprovements + skillLevel: number + comment: string + + routineCheck() : number{ + return this.skillLevel >= 13 ? this.skillLevel/2 : 0 + } + + improvementCost(){ + return DSAImprovementsTable.getCost(this.improvement, this.skillLevel) + } + + improve(){ + this.skillLevel ++ + } +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export diff --git a/src/components/Attributes.tsx b/src/components/Attributes.tsx index c0fbbc2..9dc95fe 100644 --- a/src/components/Attributes.tsx +++ b/src/components/Attributes.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import type {DSACharacter, DSAAttributes} from '../types/character'; +import type {DSACharacter} from '../types/character'; +import type {DSAAttributes} from "../types/baseCharacter.ts"; interface AttributesProps { character: DSACharacter; diff --git a/src/components/BasicInfo.tsx b/src/components/BasicInfo.tsx index 4b9030a..6e9a901 100644 --- a/src/components/BasicInfo.tsx +++ b/src/components/BasicInfo.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import type {DSACharacter} from '../types/character'; +import type {DSAPersonalData} from "../types/baseCharacter.ts"; interface BasicInfoProps { character: DSACharacter; @@ -9,7 +10,7 @@ interface BasicInfoProps { const BasicInfo: React.FC = ({ character, setCharacter }) => { const { t } = useTranslation(); - const updateField = (field: keyof DSACharacter, value: string) => { + const updateField = (field: keyof DSACharacter | keyof DSAPersonalData, value: string) => { setCharacter(prev => ({ ...prev, [field]: value @@ -25,7 +26,7 @@ const BasicInfo: React.FC = ({ character, setCharacter }) => { updateField('name', e.target.value)} placeholder={t('basicInfo.namePlaceholder')} /> @@ -35,7 +36,7 @@ const BasicInfo: React.FC = ({ character, setCharacter }) => { updateField('species', e.target.value)} placeholder={t('basicInfo.speciesPlaceholder')} /> @@ -45,7 +46,7 @@ const BasicInfo: React.FC = ({ character, setCharacter }) => { updateField('culture', e.target.value)} placeholder={t('basicInfo.culturePlaceholder')} /> @@ -55,7 +56,7 @@ const BasicInfo: React.FC = ({ character, setCharacter }) => { updateField('profession', e.target.value)} placeholder={t('basicInfo.professionPlaceholder')} /> diff --git a/src/components/CharacterSheet.tsx b/src/components/CharacterSheet.tsx index 4254f57..b3f6f1a 100644 --- a/src/components/CharacterSheet.tsx +++ b/src/components/CharacterSheet.tsx @@ -1,7 +1,7 @@ // src/components/CharacterSheet.tsx -import React, { useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import type { DSACharacter } from '../types/character'; +import React, {useState} from 'react'; +import {useTranslation} from 'react-i18next'; +import type {DSACharacter} from '../types/character'; import BasicInfo from './BasicInfo'; import Attributes from './Attributes'; import Skills from './Skills'; @@ -14,93 +14,241 @@ import '../styles/CharacterSheet.css'; // Erweiterte Initial-Daten mit Astralenergie und Zaubern const initialCharacter: DSACharacter = { - id: crypto.randomUUID(), + id: crypto.randomUUID(), + personalData: { name: '', species: '', culture: '', profession: '', - experienceLevel: 'Experienced', - attributes: { - courage: 8, - cleverness: 8, - intuition: 8, - charisma: 8, - dexterity: 8, - agility: 8, - constitution: 8, - strength: 8 + socialstatus: '', + hometown: '', + family: '', + looks: { + age: '', + haircolor: '', + eyecolor: '', + height: '', + weight: '', + characteristics: '' + } + }, + experienceLevel: 'Experienced', + health: { + lifePoints: { + max: 30, + current: 30, + base: 30, + modifier: 0, + purchased: 0 }, - skills: {}, - spells: {}, - combat: { - lifePoints: { max: 30, current: 30 }, - initiative: 10, - speed: 8 + conditions: [], + fatigue: 0, + pain: 0 + }, + attributes: { + courage: 8, + cleverness: 8, + intuition: 8, + charisma: 8, + dexterity: 8, + agility: 8, + constitution: 8, + strength: 8 + }, + skills: {}, + astral: { + spells: { + 'test': { + id: '', + name: '', + tradition: [''], + attributes: ['courage', 'agility', 'charisma'], + skillValue: 0, + aspCost: '', + castingTime: '', + range: '', + duration: '', + difficulty: 0, + description: '', + effect: '', + } }, + traditions: [], astralEnergy: { - max: 0, - current: 0 + max: 0, + current: 0 + } + }, + karmal: { + spells: { + 'test': { + id: '', + name: '', + tradition: [''], + attributes: ['courage', 'agility', 'charisma'], + skillValue: 0, + aspCost: '', + castingTime: '', + range: '', + duration: '', + difficulty: 0, + description: '', + effect: '', + } }, - magicalTraditions: [], - advantages: [], - disadvantages: [], - equipment: [] + traditions: [], + karmalEnergy: { + max: 0, + current: 0 + } + }, + hasKarmal: false, + hasMagic: false, + combat: { + initiative: 10, + speed: 8, + armor: { + 'leather': { + encumbrance: 0, + equip: { + name: 'hello', + weight: 0 + }, + penalties: 0, + protection: 0 + } + }, + combatAbilities: { + 'test': { + name: 'test' + } + }, + dodge: 0, + meleeWeapons: { + 'test': { + weapon: { + equip: { + name: 'test', + weight: 0 + }, + range: 0, + technique: 'test', + tp: 0 + }, + atpamod: 0, + at: 0, + damagebonus: 0, + pa: 0 + } + }, + rangedWeapons: { + 'javelin': { + weapon: { + equip: { + name: '', + weight: 0 + }, + technique: '', + tp: 0, + range: 0, + }, + reloaddur: 0, + ammo: { + equip: { + name: '', + weight: 0 + }, + perUse: 0, + count: 0 + }, + rangedCombat: 0, + } + }, + unarmedAttack: 0, + unarmedParry: 0 + }, + advantages: [], + disadvantages: [], + equipment: [], + resistances: { + spirit: { + base: 0, + modifier: 0, + purchased: 0, + max: 0, + current: 0 + }, + thoughness: { + base: 0, + modifier: 0, + purchased: 0, + max: 0, + current: 0, + }, + dodge: { + base: 0, + modifier: 0, + purchased: 0, + max: 0, + current: 0 + } + } }; const CharacterSheet: React.FC = () => { - const { t } = useTranslation(); - const [character, setCharacter] = useState(initialCharacter); - - // Hilfsfunktion um zu prüfen ob Charakter Zauberer ist - const isSpellcaster = character.astralEnergy && character.astralEnergy.max > 0; - - return ( -
- - - -
- {t('app.iconAlt')} -

{t('app.title')}

-
- - {/* Grundinformationen */} - - - {/* Eigenschaften */} - - - {/* Kampfwerte */} - - - {/* Fertigkeiten */} - - - {/* Zauber - nur anzeigen wenn Astralenergie > 0 oder explizit gewünscht */} - {(isSpellcaster || Object.keys(character.spells).length > 0) && ( - - )} - - {/* Button zum Hinzufügen von Zaubern falls noch kein Zauberer */} - {!isSpellcaster && Object.keys(character.spells).length === 0 && ( -
- -
- )} -
- ); + const {t} = useTranslation(); + const [character, setCharacter] = useState(initialCharacter); + + // Hilfsfunktion um zu prüfen ob Charakter Zauberer ist + const isSpellcaster = character.astral.astralEnergy && character.astral.astralEnergy.max > 0; + + return ( +
+ + + +
+ {t('app.iconAlt')} +

{t('app.title')}

+
+ + {/* Grundinformationen */} + + + {/* Eigenschaften */} + + + {/* Kampfwerte */} + + + {/* Fertigkeiten */} + + + {/* Zauber - nur anzeigen wenn Astralenergie > 0 oder explizit gewünscht */} + {(isSpellcaster || Object.keys(character.astral.spells).length > 0) && ( + + )} + + {/* Button zum Hinzufügen von Zaubern falls noch kein Zauberer */} + {!isSpellcaster && Object.keys(character.astral.spells).length === 0 && ( +
+ +
+ )} +
+ ); }; export default CharacterSheet; diff --git a/src/types/abilities.ts b/src/types/abilities.ts index 00b45a5..e4e643c 100644 --- a/src/types/abilities.ts +++ b/src/types/abilities.ts @@ -1,3 +1,36 @@ -export interface DSACombatAbilitiy { - name: string; +import type {DSAAttributes} from "./baseCharacter.ts"; +import type {DSABelastungen, DSAImprovements} from "./baseDSA.ts"; + +export interface DSABaseAbility { + name: string + steigerungsfaktor: DSAImprovements +} + +export interface DSASkill extends DSABaseAbility { + attributes: [keyof DSAAttributes, keyof DSAAttributes, keyof DSAAttributes] + fertigkeitswert: number + belastung: DSABelastungen + anmerkung: string + routineProbe: number +} + +export interface DSACombatTechnique extends DSABaseAbility { + primaryAttribute: keyof DSAAttributes + kampftechnikwert: number + hitcheck: number + paradecheck: number +} + +export interface DSASpell { + name: string + check: [keyof DSAAttributes, keyof DSAAttributes, keyof DSAAttributes] + skilllevel: number + cost: number + timeInSec: number + range: number + duration: number + property: string + improvement: DSAImprovements + effect: string[] + special: boolean } diff --git a/src/types/baseAbilities.ts b/src/types/baseAbilities.ts index 8658976..4b9eaa1 100644 --- a/src/types/baseAbilities.ts +++ b/src/types/baseAbilities.ts @@ -5,4 +5,15 @@ export interface BaseAbilities { int: number; wis: number; cha: number; -} \ No newline at end of file +} + +export interface DSAAttributes { + courage: number; + cleverness: number; + intuition: number; + charisma: number; + dexterity: number; + agility: number; + constitution: number; + strength: number; +} diff --git a/src/types/baseCharacter.ts b/src/types/baseCharacter.ts index da8d4e5..a05f7f4 100644 --- a/src/types/baseCharacter.ts +++ b/src/types/baseCharacter.ts @@ -1,4 +1,4 @@ -import type {DSACalculatedValue} from "./baseDSA.ts"; +import type {DSABelastungen, DSACalculatedValue} from "./baseDSA.ts"; export interface DSAAttributes { courage: number; @@ -13,33 +13,43 @@ export interface DSAAttributes { export interface DSAPersonalData { name: string; + sex?: 'm' | 'w' | 'd'; species: string; culture: string; profession: string; - socialstatus: string; + socialStanding: string; hometown: string; + placeOfBirth?: string; family: string; - looks: DSALooks; -} - -export interface DSALooks { age: string; - haircolor: string; - eyecolor: string; - height: string; - weight: string; - characteristics: string; + birthdate?: string; + hairColor?: string; + eyeColor?: string; + height?: string; + weight?: string; + characteristics?: string[]; + image?: string; } -export interface DSAHealth { - lifePoints: DSACalculatedValue; - conditions: string[]; - pain: number; - fatigue: number; -} - -export interface DSAResistances { +export interface DSAStats { + lifePoints: { + value: DSACalculatedValue; + pain: number; + fatigue: number; + } + conditions?: string[]; + astralEnergy?: DSACalculatedValue; + karmaEnergy?: DSACalculatedValue; spirit: DSACalculatedValue; thoughness: DSACalculatedValue; dodge: DSACalculatedValue; + initiative: number; //TODO function? + movement: number; +} + +export interface DSAExperienceLevel { + current: "Unerfahren" | "Durchschnittlich" | "Erfahren" | "Kompetent" | "Meisterlich" | "Brillant" | "Legendär" + apTotal: number + apAvailable: number + apSpent: number } diff --git a/src/types/baseDSA.ts b/src/types/baseDSA.ts index 939ede6..3c8b5dc 100644 --- a/src/types/baseDSA.ts +++ b/src/types/baseDSA.ts @@ -1,23 +1,11 @@ export interface DSACalculatedValue { base: number; modifier: number; - purchased: number; + purchased?: number; max: number; current: number; } -export interface DSAMinMaxValue { - max: number; - current: number; -} +export type DSAImprovements = 'A' | 'B' | 'C' | 'D' | 'E' | 'other' -export interface DSANamedEntity { - id: string; - name: string; - description?: string; -} - -export interface DSATimedEffect { - duration: string; - remaining?: number; -} +export type DSABelastungen = 'JA' | 'NEIN' | 'EVTL'; diff --git a/src/types/baseEquiment.ts b/src/types/baseEquiment.ts index 509dc9b..bcbec06 100644 --- a/src/types/baseEquiment.ts +++ b/src/types/baseEquiment.ts @@ -1,10 +1,10 @@ export interface DSABaseEquiment { name: string; weight: number; + carriedWhere: string; } -export interface DSABaseWeapon { - equip: DSABaseEquiment; +export interface DSABaseWeapon extends DSABaseEquiment { technique: string; tp: number; range: number; diff --git a/src/types/character.ts b/src/types/character.ts index 6f1fa82..0f33d70 100644 --- a/src/types/character.ts +++ b/src/types/character.ts @@ -1,12 +1,17 @@ import type {DSAAttributes, DSAHealth, DSAPersonalData, DSAResistances} from "./baseCharacter.ts"; import type {DSAArmor, DSAMeleeWeapon, DSARangedWeapon, DSAShield} from "./equiment.ts"; -import type {DSACombatAbilitiy} from "./abilities.ts"; +import type {DSACombatTechnique} from "./abilities.ts"; import type {DSAFatePoints} from "./fatepoints.ts"; +import type {DSABelastungen, DSAImprovements} from "./baseDSA.ts"; export interface DSASkill { - name: string; - attributes: [keyof DSAAttributes, keyof DSAAttributes, keyof DSAAttributes]; - value: number; + name: string + attributes: [keyof DSAAttributes, keyof DSAAttributes, keyof DSAAttributes] + fertigkeitswert: number + belastung: DSABelastungen + steigerungsfaktor: DSAImprovements + anmerkung: string + routineProbe: number } export interface DSACombatValues { @@ -19,7 +24,7 @@ export interface DSACombatValues { rangedWeapons: DSARangedWeapon[]; armor: DSAArmor[]; shield: DSAShield[]; - combatAbilities: Record; + combatAbilities: Record; } export interface DSAAstral { diff --git a/src/types/condition.ts b/src/types/condition.ts index 423e8dc..1773738 100644 --- a/src/types/condition.ts +++ b/src/types/condition.ts @@ -1,15 +1,4 @@ -export enum DSAConditionType { - confusion = "confusion", - encumbrance = "encumbrance", - fear = "fear", - pain = "pain", - paralysis = "paralysis", - sleep = "sleep", - rapture = "rapture", - stupor = "stupor", -} - export interface DSACondition { - condition: DSAConditionType; - level: number; -} \ No newline at end of file + condition: "confusion" | "encumbrance" | "fear" | "pain" | "paralysis" | "rapture" | "stupor"; + level: 1 | 2 | 3 | 4; +} diff --git a/src/types/equiment.ts b/src/types/equiment.ts index 71ef409..0b222be 100644 --- a/src/types/equiment.ts +++ b/src/types/equiment.ts @@ -2,36 +2,31 @@ import type {DSABaseEquiment, DSABaseWeapon} from "./baseEquiment.ts"; import type {DSACalculatedValue} from "./baseDSA.ts"; -export interface DSAAmmonution{ - equip: DSABaseEquiment; +export interface DSAAmmonution extends DSABaseEquiment { perUse: number; count: number; } -export interface DSAMeleeWeapon{ - weapon: DSABaseWeapon; +export interface DSAMeleeWeapon extends DSABaseWeapon{ atpamod: number; damagebonus: number; at: number; pa: number; } -export interface DSARangedWeapon{ - weapon: DSABaseWeapon; +export interface DSARangedWeapon extends DSABaseWeapon{ reloaddur: number; ammo: DSAAmmonution; rangedCombat: number; } -export interface DSAArmor{ - equip: DSABaseEquiment; +export interface DSAArmor extends DSABaseEquiment{ protection: number; encumbrance: number; penalties: number; } -export interface DSAShield{ - equip: DSABaseEquiment; +export interface DSAShieldParryWeapon extends DSABaseEquiment { structure: DSACalculatedValue; atpamod: number; -} \ No newline at end of file +} diff --git a/tsconfig.app.json b/tsconfig.app.json index 3cd9a0b..c9ccbd4 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -19,7 +19,7 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "erasableSyntaxOnly": false, + "erasableSyntaxOnly": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, diff --git a/tsconfig.node.json b/tsconfig.node.json index fa3809c..9728af2 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -17,7 +17,7 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "erasableSyntaxOnly": false, + "erasableSyntaxOnly": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true },