rework races

This commit is contained in:
2026-05-16 18:35:55 +02:00
parent 83f2b555f8
commit b0a4bd554e
5 changed files with 63 additions and 34 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ export function newCharacter(partial?: { name?: string; id?: string }): Characte
schemaVersion: CURRENT_SCHEMA_VERSION,
meta: {
name,
rasse: 'Mensch',
rasse: 'mensch01',
kultur: '',
profession: ''
},
+9 -6
View File
@@ -1,6 +1,6 @@
import type { AttributeKey } from '$lib/rules/attributes';
import type { Character } from '$lib/schema/character';
import { RACE_ASP_MOD, RACE_LEP_MOD } from '$lib/rules/races';
import { getRaceDef } from '$lib/rules/races';
export function effectiveAttr(char: Character, key: AttributeKey): number {
const a = char.eigenschaften[key];
@@ -36,11 +36,13 @@ export function iniBasis(char: Character): number {
return Math.round(v);
}
/** MR-Basis = (MU + KL + KO) / 5 + MR-Mod aus Energien */
/** MR-Basis = (MU + KL + KO) / 5 + MR-Mod aus Energien + Rassen-MR */
export function mrBasis(char: Character): number {
const race = getRaceDef(char.meta.rasse);
const v =
(effectiveAttr(char, 'MU') + effectiveAttr(char, 'KL') + effectiveAttr(char, 'KO')) / 5 +
char.energien.mr.mod;
char.energien.mr.mod +
(race?.mr_mod ?? 0);
return Math.round(v);
}
@@ -49,20 +51,21 @@ export function lepMax(char: Character): number {
const ko = effectiveAttr(char, 'KO');
const kk = effectiveAttr(char, 'KK');
const base = Math.floor((2 * ko + kk) / 2);
const race = RACE_LEP_MOD[char.meta.rasse] ?? 0;
const race = getRaceDef(char.meta.rasse)?.lep_mod ?? 0;
return base + race + char.energien.lep.mod;
}
export function aspMax(char: Character): number {
if (!char.energien.asp) return 0;
const race = RACE_ASP_MOD[char.meta.rasse] ?? 0;
const race = getRaceDef(char.meta.rasse)?.asp_mod ?? 0;
const base = effectiveAttr(char, 'IN') + effectiveAttr(char, 'IN') + effectiveAttr(char, 'CH');
return Math.max(0, base + race + char.energien.asp.mod);
}
export function aupMax(char: Character): number {
const race = getRaceDef(char.meta.rasse)?.aup_mod ?? 0;
const base = effectiveAttr(char, 'MU') + effectiveAttr(char, 'MU') + effectiveAttr(char, 'IN');
return Math.max(0, base + char.energien.aup.mod);
return Math.max(0, base + race + char.energien.aup.mod);
}
export type DerivedSheet = {
+44 -24
View File
@@ -1,26 +1,46 @@
/** LeP-Modifikator je Rasse (typische Werte DSA 4.1, vereinfacht) */
export const RACE_LEP_MOD: Record<string, number> = {
Mensch: 5,
Elf: 2,
Halbelf: 4,
Zwerg: 8,
Halbling: 0,
Gnom: -4,
Halbork: 6,
Ork: 8,
Goblin: -5,
'': 0
/** Rassen mit LeP-/AuP-/AsP-/MR-Modifikatoren (typische Werte DSA 4.1, vereinfacht) */
export type RaceDef = {
id: string;
name: string;
lep_mod: number;
aup_mod: number;
asp_mod: number;
mr_mod: number;
};
export const RACE_ASP_MOD: Record<string, number> = {
Mensch: 0,
Elf: 12,
Halbelf: 6,
Zwerg: 0,
Halbling: 0,
Gnom: 0,
Halbork: 0,
Ork: 0,
Goblin: 0,
'': 0
};
export const RACES: RaceDef[] = [
{ id: 'mensch01', name: 'Mittelländer', lep_mod: 10, aup_mod: 10, asp_mod: 0, mr_mod: -4 },
{ id: 'mensch02', name: 'Tulamide', lep_mod: 10, aup_mod: 10, asp_mod: 0, mr_mod: -4 },
{ id: 'mensch03', name: 'Thorwaler', lep_mod: 11, aup_mod: 10, asp_mod: 0, mr_mod: -5 },
{ id: 'mensch04', name: 'Nivese', lep_mod: 9, aup_mod: 12, asp_mod: 0, mr_mod: -5 },
{ id: 'mensch05', name: 'Norbarde', lep_mod: 11, aup_mod: 10, asp_mod: 0, mr_mod: -4 },
{ id: 'mensch06', name: 'Trollzacker', lep_mod: 11, aup_mod: 18, asp_mod: 0, mr_mod: -5 },
{ id: 'mensch07', name: 'Rochshaz', lep_mod: 12, aup_mod: 20, asp_mod: 0, mr_mod: -5 },
{ id: 'mensch08', name: 'Waldmensch', lep_mod: 8, aup_mod: 12, asp_mod: 0, mr_mod: -6 },
{ id: 'mensch09', name: 'Tocamuyac', lep_mod: 8, aup_mod: 12, asp_mod: 0, mr_mod: -6 },
{ id: 'mensch10', name: 'Utulu', lep_mod: 11, aup_mod: 12, asp_mod: 0, mr_mod: -6 },
{ id: 'plainelf', name: 'Auelf', lep_mod: 6, aup_mod: 12, asp_mod: 12, mr_mod: -2 },
{ id: 'woodelf', name: 'Waldelf', lep_mod: 6, aup_mod: 10, asp_mod: 12, mr_mod: -2 },
{ id: 'firnelf', name: 'Firnelf', lep_mod: 7, aup_mod: 15, asp_mod: 12, mr_mod: -1 },
{ id: 'halbelf', name: 'Halbelf', lep_mod: 8, aup_mod: 10, asp_mod: -6, mr_mod: -4 },
{ id: 'zwerg01', name: 'Zwerg', lep_mod: 11, aup_mod: 15, asp_mod: 0, mr_mod: -4 },
{ id: 'zwerg02', name: 'Brilliantzwerg', lep_mod: 10, aup_mod: 18, asp_mod: 0, mr_mod: -4 },
{ id: 'zwerg03', name: 'Ambosszwerg', lep_mod: 12, aup_mod: 18, asp_mod: 0, mr_mod: -4 },
{ id: 'ork01', name: 'Ork', lep_mod: 12, aup_mod: 18, asp_mod: 0, mr_mod: -7 },
{ id: 'ork02', name: 'Orkfrau', lep_mod: 10, aup_mod: 15, asp_mod: 0, mr_mod: -7 },
{ id: 'halbork', name: 'Halbork', lep_mod: 11, aup_mod: 15, asp_mod: 0, mr_mod: -6 },
{ id: 'goblin', name: 'Goblin', lep_mod: 4, aup_mod: 12, asp_mod: 0, mr_mod: -5 },
{ id: 'achaz01', name: 'Achaz', lep_mod: 8, aup_mod: 7, asp_mod: 0, mr_mod: -2 },
{ id: 'achaz02', name: 'Orkland-Achaz', lep_mod: 15, aup_mod: 7, asp_mod: 0, mr_mod: -2 },
{ id: 'achaz03', name: 'Maraskan-Achaz', lep_mod: 15, aup_mod: 7, asp_mod: 0, mr_mod: -2 }
];
export function getRaceDef(rasse: string): RaceDef | undefined {
if (!rasse) return undefined;
const byId = RACES.find((r) => r.id === rasse);
if (byId) return byId;
const lower = rasse.toLowerCase();
const byIdLower = RACES.find((r) => r.id === lower);
if (byIdLower) return byIdLower;
return RACES.find((r) => r.name === rasse);
}
@@ -4,6 +4,7 @@
import type { Character } from '$lib/schema/character';
import { ATTRIBUTE_KEYS, ATTRIBUTE_LABELS } from '$lib/rules/attributes';
import { getCharacter, saveCharacter } from '$lib/storage/repo';
import { RACES } from '$lib/rules/races';
import { TALENTS } from '$lib/rules/talents';
import { computeDerived } from '$lib/engine/derived';
import { atBasis, paBasis } from '$lib/engine/derived';
@@ -116,7 +117,12 @@
</div>
<div class="field">
<label for="rasse">Rasse</label>
<input id="rasse" bind:value={char.meta.rasse} />
<select id="rasse" bind:value={char.meta.rasse}>
<option value=""></option>
{#each RACES as r}
<option value={r.id}>{r.name}</option>
{/each}
</select>
</div>
<div class="field">
<label for="kultur">Kultur</label>