Add NPC creation and titles retrieval functionality in Admin module

- Implemented createNPCs method in AdminController to handle NPC creation with specified parameters including region, age, title, and count.
- Added getTitlesOfNobility method in AdminController to retrieve available titles for users.
- Updated adminRouter to include new routes for creating NPCs and fetching titles.
- Enhanced navigationController and frontend localization files to support new NPC creation feature.
- Introduced corresponding UI components and routes for NPC management in the admin interface.
This commit is contained in:
Torsten Schulz (local)
2026-01-07 16:45:39 +01:00
parent 511df52c3c
commit bb91c2bbe5
11 changed files with 549 additions and 19 deletions

View File

@@ -635,20 +635,27 @@ class FalukantService extends BaseService {
});
if (already > 0) return null;
// Choose an event (guaranteed once/day, random type)
// Choose an event (reduced frequency - not guaranteed every day)
// Total weight: 50 (50% chance per day, or adjust as needed)
const events = [
{ id: 'windfall', weight: 25 },
{ id: 'theft', weight: 20 },
{ id: 'character_illness', weight: 20 },
{ id: 'character_recovery', weight: 15 },
{ id: 'character_accident', weight: 10 },
{ id: 'regional_festival', weight: 10 },
// Regionale Events sind sehr selten und sollten nicht alle Charaktere töten
{ id: 'windfall', weight: 10 },
{ id: 'theft', weight: 8 },
{ id: 'character_illness', weight: 8 },
{ id: 'character_recovery', weight: 6 },
{ id: 'character_accident', weight: 4 },
{ id: 'regional_festival', weight: 4 },
// Regionale Events sind sehr selten
{ id: 'regional_storm', weight: 1 },
{ id: 'regional_epidemic', weight: 1 },
{ id: 'earthquake', weight: 1 },
];
const total = events.reduce((s, e) => s + e.weight, 0);
// Reduzierte Wahrscheinlichkeit: Nur 30% Chance pro Tag, dass ein Event auftritt
const eventChance = 0.3;
if (Math.random() > eventChance) {
return null; // Kein Event heute
}
let r = Math.random() * total;
let chosen = events[0].id;
for (const e of events) {
@@ -686,9 +693,9 @@ class FalukantService extends BaseService {
const name = [character?.definedFirstName?.name, character?.definedLastName?.name].filter(Boolean).join(' ').trim();
payload.characterName = name || null;
let delta = 0;
if (chosen === 'character_illness') delta = -(Math.floor(Math.random() * 11) + 5); // -5..-15
if (chosen === 'character_illness') delta = -(Math.floor(Math.random() * 10) + 1); // -1..-10
if (chosen === 'character_recovery') delta = (Math.floor(Math.random() * 11) + 5); // +5..+15
if (chosen === 'character_accident') delta = -(Math.floor(Math.random() * 16) + 10); // -10..-25
if (chosen === 'character_accident') delta = -(Math.floor(Math.random() * 24) + 2); // -2..-25
payload.healthChange = delta > 0 ? `+${delta}` : `${delta}`;
if (character) {
const next = Math.min(100, Math.max(0, Number(character.health || 0) + delta));
@@ -704,20 +711,20 @@ class FalukantService extends BaseService {
// Regionale Events sollten nur einen moderaten Health-Verlust verursachen
// NICHT alle Charaktere töten!
if (chosen === 'regional_epidemic' && character) {
// Moderate Health-Reduktion: -10 bis -20 (nicht tödlich!)
const delta = -(Math.floor(Math.random() * 11) + 10); // -10..-20
// Moderate Health-Reduktion: -3 bis -7 (reduziert)
const delta = -(Math.floor(Math.random() * 5) + 3); // -3..-7
payload.healthChange = `${delta}`;
const next = Math.min(100, Math.max(0, Number(character.health || 0) + delta));
await character.update({ health: next }, { transaction: t });
} else if (chosen === 'regional_storm' && character) {
// Sehr geringer Health-Verlust: -5 bis -10
const delta = -(Math.floor(Math.random() * 6) + 5); // -5..-10
// Sehr geringer Health-Verlust: -2 bis -5
const delta = -(Math.floor(Math.random() * 4) + 2); // -2..-5
payload.healthChange = `${delta}`;
const next = Math.min(100, Math.max(0, Number(character.health || 0) + delta));
await character.update({ health: next }, { transaction: t });
} else if (chosen === 'earthquake' && character) {
// Moderate Health-Reduktion: -15 bis -25 (kann gefährlich sein, aber nicht tödlich)
const delta = -(Math.floor(Math.random() * 11) + 15); // -15..-25
// Moderate Health-Reduktion: -5 bis -10 (reduziert)
const delta = -(Math.floor(Math.random() * 6) + 5); // -5..-10
payload.healthChange = `${delta}`;
const next = Math.min(100, Math.max(0, Number(character.health || 0) + delta));
await character.update({ health: next }, { transaction: t });