diff --git a/src/assets/react.svg b/src/assets/react.svg deleted file mode 100644 index 6c87de9..0000000 --- a/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/components/CharacterSheet.tsx b/src/components/CharacterSheet.tsx index 3105be1..4254f57 100644 --- a/src/components/CharacterSheet.tsx +++ b/src/components/CharacterSheet.tsx @@ -9,7 +9,6 @@ import Spells from './Spells'; import CombatValues from './CombatValues'; import ThemeToggle from './ThemeToggle'; import LanguageSelector from './LanguageSelector'; -import DSADiceRoller from "./DSADiceRoller.tsx"; import iconUrl from '/icon.png'; import '../styles/CharacterSheet.css'; @@ -32,18 +31,17 @@ const initialCharacter: DSACharacter = { strength: 8 }, skills: {}, - spells: {}, // ← Neu hinzugefügt + spells: {}, combat: { lifePoints: { max: 30, current: 30 }, - stamina: { max: 30, current: 30 }, initiative: 10, speed: 8 }, - astralEnergy: { // ← Neu hinzugefügt für Zauberer + astralEnergy: { max: 0, current: 0 }, - magicalTraditions: [], // ← Neu hinzugefügt + magicalTraditions: [], advantages: [], disadvantages: [], equipment: [] @@ -82,9 +80,6 @@ const CharacterSheet: React.FC = () => { {/* Fertigkeiten */} - {/* Würfel-Integration - kommt nach Skills */} - - {/* Zauber - nur anzeigen wenn Astralenergie > 0 oder explizit gewünscht */} {(isSpellcaster || Object.keys(character.spells).length > 0) && ( diff --git a/src/components/CombatValues.tsx b/src/components/CombatValues.tsx index 5a1a125..08bec9b 100644 --- a/src/components/CombatValues.tsx +++ b/src/components/CombatValues.tsx @@ -7,7 +7,7 @@ interface CombatValuesProps { } const CombatValues: React.FC = ({ character, setCharacter }) => { - const updateCombatValue = (category: 'lifePoints' | 'stamina' | 'astralEnergy', + const updateCombatValue = (category: 'lifePoints' | 'astralEnergy', field: 'max' | 'current', value: number) => { setCharacter(prev => ({ @@ -62,32 +62,6 @@ const CombatValues: React.FC = ({ character, setCharacter }) -
-

Stamina

-
-
- - updateCombatValue('stamina', 'current', parseInt(e.target.value) || 0)} - min="0" - /> -
-
- - updateCombatValue('stamina', 'max', parseInt(e.target.value) || 0)} - min="0" - /> -
-
-
-
diff --git a/src/components/DSADiceRoller.tsx b/src/components/DSADiceRoller.tsx deleted file mode 100644 index 27bd2eb..0000000 --- a/src/components/DSADiceRoller.tsx +++ /dev/null @@ -1,199 +0,0 @@ -import React, { useState } from 'react'; -import type { DSACharacter, DSASkill, DSASpell } from '../types/character'; -import { useTaleSpireDice } from '../hooks/useTaleSpireDice'; - -interface DSADiceRollerProps { - character: DSACharacter; -} - -const DSADiceRoller: React.FC = ({ character }) => { - const { rollDSACheck, rollSimpleDice, isAvailable } = useTaleSpireDice(); - const [modifier, setModifier] = useState(0); - const [lastResult, setLastResult] = useState(null); - - const rollAttributeCheck = async (attributeKey: keyof typeof character.attributes) => { - const attributeValue = character.attributes[attributeKey]; - try { - const result = await rollDSACheck( - [attributeValue, attributeValue, attributeValue], - 0, - modifier, - `${attributeKey.toUpperCase()} Probe` - ); - setLastResult(result); - } catch (error) { - console.error('Dice roll failed:', error); - } - }; - - const rollSkillCheck = async (skill: DSASkill) => { - const [attr1, attr2, attr3] = skill.attributes; - const attributes: [number, number, number] = [ - character.attributes[attr1], - character.attributes[attr2], - character.attributes[attr3] - ]; - - try { - const result = await rollDSACheck( - attributes, - skill.value, - modifier, - `${skill.name} Probe` - ); - setLastResult(result); - } catch (error) { - console.error('Skill roll failed:', error); - } - }; - - const rollSpellCheck = async (spell: DSASpell) => { - const [attr1, attr2, attr3] = spell.attributes; - const attributes: [number, number, number] = [ - character.attributes[attr1], - character.attributes[attr2], - character.attributes[attr3] - ]; - - try { - const result = await rollDSACheck( - attributes, - spell.skillValue, - modifier + spell.difficulty, - `${spell.name} Zauberprobe` - ); - setLastResult(result); - } catch (error) { - console.error('Spell roll failed:', error); - } - }; - - const rollInitiative = async () => { - try { - const result = await rollSimpleDice('1d6', 'Initiative'); - const total = result.total + character.combat.initiative; - setLastResult({ ...result, total, type: 'initiative' }); - } catch (error) { - console.error('Initiative roll failed:', error); - } - }; - - return ( -
-

🎲 Würfelproben

- - {!isAvailable && ( -
- ⚠️ TaleSpire Dice API nicht verfügbar - Development Mode aktiv -
- )} - - {/* Modifikator */} -
- - setModifier(parseInt(e.target.value) || 0)} - min="-10" - max="10" - className="modifier-input" - /> -
- - {/* Letztes Ergebnis */} - {lastResult && ( -
-

Letztes Ergebnis:

-
-
Würfel: {lastResult.dice?.join(', ')}
- {lastResult.type === 'initiative' ? ( -
Initiative: {lastResult.total}
- ) : ( - <> -
{lastResult.success ? '✅ Erfolg' : '❌ Fehlschlag'}
- {lastResult.success && ( -
Qualitätsstufe: {lastResult.qualityLevel}
- )} - - )} -
-
- )} - - {/* Eigenschaften */} -
-

Eigenschaftsproben

-
- {Object.entries(character.attributes).map(([key, value]) => ( - - ))} -
-
- - {/* Fertigkeiten */} - {Object.keys(character.skills).length > 0 && ( -
-

Fertigkeitsproben

-
- {Object.values(character.skills).slice(0, 6).map((skill) => ( - - ))} -
-
- )} - - {/* Zauberproben */} - {Object.keys(character.spells).length > 0 && ( -
-

Zauberproben

-
- {Object.values(character.spells).slice(0, 4).map((spell) => ( - - ))} -
-
- )} - - {/* Kampf */} -
-

Kampfwürfe

-
- - -
-
-
- ); -}; - -export default DSADiceRoller; \ No newline at end of file diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index 46f7cd2..d1791aa 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json @@ -14,6 +14,12 @@ "culturePlaceholder": "z.B. Mittelländisch, Thorwalsch", "profession": "Profession", "professionPlaceholder": "z.B. Krieger, Magier, Kundschafter", + "socialstatus": "Sozialstatus", + "socialstatusPlaceholder": "z.B. Unfrei, Bürger, Adel", + "hometown": "Heimatort", + "hometownPlaceholder": "Geburts- oder Heimatort", + "family": "Familie", + "familyPlaceholder": "Familienstand und Verwandtschaft", "experienceLevel": "Erfahrungsstufe", "experienceLevels": { "inexperienced": "Unerfahren", @@ -25,6 +31,21 @@ "legendary": "Legendär" } }, + "appearance": { + "title": "Aussehen", + "age": "Alter", + "agePlaceholder": "Alter in Jahren", + "haircolor": "Haarfarbe", + "haircolorPlaceholder": "z.B. Braun, Blond, Schwarz", + "eyecolor": "Augenfarbe", + "eyecolorPlaceholder": "z.B. Braun, Blau, Grün", + "height": "Größe", + "heightPlaceholder": "Größe in cm", + "weight": "Gewicht", + "weightPlaceholder": "Gewicht in kg", + "characteristics": "Besondere Merkmale", + "characteristicsPlaceholder": "Narben, Tätowierungen, etc." + }, "attributes": { "title": "Eigenschaften", "courage": "MU - Mut", @@ -39,16 +60,62 @@ "combat": { "title": "Kampfwerte", "lifePoints": "Lebenspunkte", - "stamina": "Ausdauer", + "astralEnergy": "Astralpunkte", "initiative": "Initiative", - "speed": "Geschwindigkeit" + "speed": "Geschwindigkeit", + "max": "Max", + "current": "Aktuell" }, "skills": { - "title": "Fertigkeiten" + "title": "Fertigkeiten", + "skillValue": "FW", + "addSkill": "Fertigkeit hinzufügen" + }, + "advantages": { + "title": "Vorteile", + "addAdvantage": "Vorteil hinzufügen" + }, + "disadvantages": { + "title": "Nachteile", + "addDisadvantage": "Nachteil hinzufügen" + }, + "equipment": { + "title": "Ausrüstung", + "addEquipment": "Ausrüstung hinzufügen" }, "spells": { "title": "Zauber", - "addMagic": "🪄 Zauberfähigkeiten hinzufügen" + "addMagic": "Zauberfähigkeiten hinzufügen", + "addSpell": "Zauber hinzufügen", + "magicalTraditions": "Magische Traditionen", + "tradition": "Tradition", + "skillValue": "ZfW - Zauberfertigkeit", + "aspCost": "AsP-Kosten", + "castingTime": "Zauberdauer", + "range": "Reichweite", + "duration": "Wirkungsdauer", + "difficulty": "Erschwernis", + "description": "Beschreibung", + "effect": "Wirkung", + "traditions": { + "gildenmagier": "Gildenmagier", + "hexe": "Hexe", + "druide": "Druide", + "elf": "Elf", + "scharlatane": "Scharlatane", + "zauberbarde": "Zauberbarde", + "zaubertänzer": "Zaubertänzer", + "intuitivezauberer": "Intuitive Zauberer" + } + }, + "common": { + "save": "Speichern", + "cancel": "Abbrechen", + "edit": "Bearbeiten", + "delete": "Löschen", + "add": "Hinzufügen", + "close": "Schließen", + "confirm": "Bestätigen" } } -} +} \ No newline at end of file diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 7532c31..d534734 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -48,7 +48,7 @@ }, "spells": { "title": "Spells", - "addMagic": "🪄 Add Magic Abilities" + "addMagic": "Add Magic Abilities" } } } diff --git a/src/types/baseCharacter.ts b/src/types/baseCharacter.ts new file mode 100644 index 0000000..86bdf02 --- /dev/null +++ b/src/types/baseCharacter.ts @@ -0,0 +1,46 @@ +import type {DSACalculatedValue} from "./baseDSA.ts"; + +export interface DSAAttributes { + courage: number; + cleverness: number; + intuition: number; + charisma: number; + dexterity: number; + agility: number; + constitution: number; + strength: number; +} + +export interface DSAPersonalData { + id: string; + name: string; + species: string; + culture: string; + profession: string; + socialstatus: string; + hometown: string; + family: string; + looks: DSALooks; +} + +export interface DSALooks { + age: string; + haircolor: string; + eyecolor: string; + height: string; + weight: string; + characteristics: string; +} + +export interface DSAHealth { + lifePoints: DSACalculatedValue; + conditions: string[]; + pain: number; + fatigue: number; +} + +export interface DSAResistances { + spirit: DSACalculatedValue; + thoughness: DSACalculatedValue; + dodge: DSACalculatedValue; +} diff --git a/src/types/baseDSA.ts b/src/types/baseDSA.ts new file mode 100644 index 0000000..939ede6 --- /dev/null +++ b/src/types/baseDSA.ts @@ -0,0 +1,23 @@ +export interface DSACalculatedValue { + base: number; + modifier: number; + purchased: number; + max: number; + current: number; +} + +export interface DSAMinMaxValue { + max: number; + current: number; +} + +export interface DSANamedEntity { + id: string; + name: string; + description?: string; +} + +export interface DSATimedEffect { + duration: string; + remaining?: number; +} diff --git a/src/types/character.ts b/src/types/character.ts index e0fbcdb..fe5f16b 100644 --- a/src/types/character.ts +++ b/src/types/character.ts @@ -1,13 +1,4 @@ -export interface DSAAttributes { - courage: number; // Mut - cleverness: number; // Klugheit - intuition: number; // Intuition - charisma: number; // Charisma - dexterity: number; // Fingerfertigkeit - agility: number; // Gewandtheit - constitution: number; // Konstitution - strength: number; // Körperkraft -} +import type {DSAAttributes, DSAHealth, DSAPersonalData, DSAResistances} from "./baseCharacter.ts"; export interface DSASkill { name: string; @@ -16,54 +7,62 @@ export interface DSASkill { } export interface DSACombatValues { - lifePoints: { - max: number; - current: number; - }; - stamina: { - max: number; - current: number; - }; - astralEnergy?: { - max: number; - current: number; - }; initiative: number; speed: number; + dodge: number; + unarmedAttack: number; + unarmedParry: number; + weapons: Record; + armor: Record; + combatAbilities: Record; } -export interface DSASpell { - id: string; - name: string; - tradition: string[]; // Gildenmagier, Hexe, Druide, etc. - attributes: [keyof DSAAttributes, keyof DSAAttributes, keyof DSAAttributes]; - skillValue: number; // FW - Fertigkeitswert - aspCost: string; // "4 AsP", "2 AsP pro Stufe" - castingTime: string; // "2 Aktionen", "5 Minuten" - range: string; // "Berührung", "7 Meter" - duration: string; // "Sofort", "5 Minuten" - difficulty: number; // Erschwernis/Erleichterung - description: string; - effect: string; -} - -export interface DSACharacter { - id: string; - name: string; - species: string; // Spezies - culture: string; // Kultur - profession: string; // Profession - experienceLevel: string; // Erfahrungsgrad - attributes: DSAAttributes; - skills: Record; - combat: DSACombatValues; - advantages: string[]; // Vorteile - disadvantages: string[]; // Nachteile - equipment: string[]; // Ausrüstung +export interface DSAAstral { astralEnergy?: { max: number; current: number; }; spells: Record; - magicalTraditions: string[]; + traditions: string[]; +} + +export interface DSAKarmal { + karmalEnergy?: { + max: number; + current: number; + } + spells: Record; + traditions: string[]; +} + +export interface DSASpell { + id: string; + name: string; + tradition: string[]; + attributes: [keyof DSAAttributes, keyof DSAAttributes, keyof DSAAttributes]; + skillValue: number; + aspCost: string; + castingTime: string; + range: string; + duration: string; + difficulty: number; + description: string; + effect: string; +} + +export interface DSACharacter { + personalData: DSAPersonalData; + experienceLevel: string; + attributes: DSAAttributes; + health: DSAHealth; + resistances: DSAResistances; + skills: Record; + combat: DSACombatValues; + advantages: string[]; + disadvantages: string[]; + equipment: string[]; + hasMagic: boolean; + astral: DSAAstral; + hasKarmal: boolean; + karmal: DSAKarmal; }