rework races
This commit is contained in:
@@ -24,7 +24,7 @@ export function newCharacter(partial?: { name?: string; id?: string }): Characte
|
|||||||
schemaVersion: CURRENT_SCHEMA_VERSION,
|
schemaVersion: CURRENT_SCHEMA_VERSION,
|
||||||
meta: {
|
meta: {
|
||||||
name,
|
name,
|
||||||
rasse: 'Mensch',
|
rasse: 'mensch01',
|
||||||
kultur: '',
|
kultur: '',
|
||||||
profession: ''
|
profession: ''
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { AttributeKey } from '$lib/rules/attributes';
|
import type { AttributeKey } from '$lib/rules/attributes';
|
||||||
import type { Character } from '$lib/schema/character';
|
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 {
|
export function effectiveAttr(char: Character, key: AttributeKey): number {
|
||||||
const a = char.eigenschaften[key];
|
const a = char.eigenschaften[key];
|
||||||
@@ -36,11 +36,13 @@ export function iniBasis(char: Character): number {
|
|||||||
return Math.round(v);
|
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 {
|
export function mrBasis(char: Character): number {
|
||||||
|
const race = getRaceDef(char.meta.rasse);
|
||||||
const v =
|
const v =
|
||||||
(effectiveAttr(char, 'MU') + effectiveAttr(char, 'KL') + effectiveAttr(char, 'KO')) / 5 +
|
(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);
|
return Math.round(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,20 +51,21 @@ export function lepMax(char: Character): number {
|
|||||||
const ko = effectiveAttr(char, 'KO');
|
const ko = effectiveAttr(char, 'KO');
|
||||||
const kk = effectiveAttr(char, 'KK');
|
const kk = effectiveAttr(char, 'KK');
|
||||||
const base = Math.floor((2 * ko + kk) / 2);
|
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;
|
return base + race + char.energien.lep.mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function aspMax(char: Character): number {
|
export function aspMax(char: Character): number {
|
||||||
if (!char.energien.asp) return 0;
|
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');
|
const base = effectiveAttr(char, 'IN') + effectiveAttr(char, 'IN') + effectiveAttr(char, 'CH');
|
||||||
return Math.max(0, base + race + char.energien.asp.mod);
|
return Math.max(0, base + race + char.energien.asp.mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function aupMax(char: Character): number {
|
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');
|
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 = {
|
export type DerivedSheet = {
|
||||||
|
|||||||
+44
-24
@@ -1,26 +1,46 @@
|
|||||||
/** LeP-Modifikator je Rasse (typische Werte DSA 4.1, vereinfacht) */
|
/** Rassen mit LeP-/AuP-/AsP-/MR-Modifikatoren (typische Werte DSA 4.1, vereinfacht) */
|
||||||
export const RACE_LEP_MOD: Record<string, number> = {
|
export type RaceDef = {
|
||||||
Mensch: 5,
|
id: string;
|
||||||
Elf: 2,
|
name: string;
|
||||||
Halbelf: 4,
|
lep_mod: number;
|
||||||
Zwerg: 8,
|
aup_mod: number;
|
||||||
Halbling: 0,
|
asp_mod: number;
|
||||||
Gnom: -4,
|
mr_mod: number;
|
||||||
Halbork: 6,
|
|
||||||
Ork: 8,
|
|
||||||
Goblin: -5,
|
|
||||||
'': 0
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RACE_ASP_MOD: Record<string, number> = {
|
export const RACES: RaceDef[] = [
|
||||||
Mensch: 0,
|
{ id: 'mensch01', name: 'Mittelländer', lep_mod: 10, aup_mod: 10, asp_mod: 0, mr_mod: -4 },
|
||||||
Elf: 12,
|
{ id: 'mensch02', name: 'Tulamide', lep_mod: 10, aup_mod: 10, asp_mod: 0, mr_mod: -4 },
|
||||||
Halbelf: 6,
|
{ id: 'mensch03', name: 'Thorwaler', lep_mod: 11, aup_mod: 10, asp_mod: 0, mr_mod: -5 },
|
||||||
Zwerg: 0,
|
{ id: 'mensch04', name: 'Nivese', lep_mod: 9, aup_mod: 12, asp_mod: 0, mr_mod: -5 },
|
||||||
Halbling: 0,
|
{ id: 'mensch05', name: 'Norbarde', lep_mod: 11, aup_mod: 10, asp_mod: 0, mr_mod: -4 },
|
||||||
Gnom: 0,
|
{ id: 'mensch06', name: 'Trollzacker', lep_mod: 11, aup_mod: 18, asp_mod: 0, mr_mod: -5 },
|
||||||
Halbork: 0,
|
{ id: 'mensch07', name: 'Rochshaz', lep_mod: 12, aup_mod: 20, asp_mod: 0, mr_mod: -5 },
|
||||||
Ork: 0,
|
{ id: 'mensch08', name: 'Waldmensch', lep_mod: 8, aup_mod: 12, asp_mod: 0, mr_mod: -6 },
|
||||||
Goblin: 0,
|
{ id: 'mensch09', name: 'Tocamuyac', lep_mod: 8, aup_mod: 12, asp_mod: 0, mr_mod: -6 },
|
||||||
'': 0
|
{ 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 type { Character } from '$lib/schema/character';
|
||||||
import { ATTRIBUTE_KEYS, ATTRIBUTE_LABELS } from '$lib/rules/attributes';
|
import { ATTRIBUTE_KEYS, ATTRIBUTE_LABELS } from '$lib/rules/attributes';
|
||||||
import { getCharacter, saveCharacter } from '$lib/storage/repo';
|
import { getCharacter, saveCharacter } from '$lib/storage/repo';
|
||||||
|
import { RACES } from '$lib/rules/races';
|
||||||
import { TALENTS } from '$lib/rules/talents';
|
import { TALENTS } from '$lib/rules/talents';
|
||||||
import { computeDerived } from '$lib/engine/derived';
|
import { computeDerived } from '$lib/engine/derived';
|
||||||
import { atBasis, paBasis } from '$lib/engine/derived';
|
import { atBasis, paBasis } from '$lib/engine/derived';
|
||||||
@@ -116,7 +117,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="rasse">Rasse</label>
|
<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>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="kultur">Kultur</label>
|
<label for="kultur">Kultur</label>
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ describe('derived', () => {
|
|||||||
|
|
||||||
it('includes race LeP bonus for human', () => {
|
it('includes race LeP bonus for human', () => {
|
||||||
const c = newCharacter({ name: 'H', id: '00000000-0000-4000-8000-000000000002' });
|
const c = newCharacter({ name: 'H', id: '00000000-0000-4000-8000-000000000002' });
|
||||||
c.meta.rasse = 'Mensch';
|
c.meta.rasse = 'Mittelländer';
|
||||||
const ko = 12;
|
const ko = 12;
|
||||||
const kk = 13;
|
const kk = 13;
|
||||||
c.eigenschaften.KO = { startwert: ko, mod: 0 };
|
c.eigenschaften.KO = { startwert: ko, mod: 0 };
|
||||||
c.eigenschaften.KK = { startwert: kk, mod: 0 };
|
c.eigenschaften.KK = { startwert: kk, mod: 0 };
|
||||||
const base = Math.floor((2 * ko + kk) / 2);
|
const base = Math.floor((2 * ko + kk) / 2);
|
||||||
expect(lepMax(c)).toBe(base + 5 + c.energien.lep.mod);
|
expect(lepMax(c)).toBe(base + 10 + c.energien.lep.mod);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('computeDerived returns all keys', () => {
|
it('computeDerived returns all keys', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user