Add regional event handling and character creation logic in FalukantService

- Introduced new regional events ('regional_storm', 'regional_epidemic', 'earthquake') with specific health impact mechanics to enhance gameplay dynamics.
- Updated health modification logic to ensure regional events cause moderate health loss rather than fatal outcomes.
- Implemented character creation logic to generate potential heirs when none are found, including random gender, names, and age attributes.
- Enhanced heir retrieval process to include newly created characters, ensuring a seamless user experience.
This commit is contained in:
Torsten Schulz (local)
2026-01-07 11:13:54 +01:00
parent c90b7785c0
commit 75dbd78da1

View File

@@ -643,6 +643,10 @@ class FalukantService extends BaseService {
{ id: 'character_recovery', weight: 15 }, { id: 'character_recovery', weight: 15 },
{ id: 'character_accident', weight: 10 }, { id: 'character_accident', weight: 10 },
{ id: 'regional_festival', weight: 10 }, { id: 'regional_festival', weight: 10 },
// Regionale Events sind sehr selten und sollten nicht alle Charaktere töten
{ id: 'regional_storm', weight: 1 },
{ id: 'regional_epidemic', weight: 1 },
{ id: 'earthquake', weight: 1 },
]; ];
const total = events.reduce((s, e) => s + e.weight, 0); const total = events.reduce((s, e) => s + e.weight, 0);
let r = Math.random() * total; let r = Math.random() * total;
@@ -690,12 +694,34 @@ class FalukantService extends BaseService {
const next = Math.min(100, Math.max(0, Number(character.health || 0) + delta)); const next = Math.min(100, Math.max(0, Number(character.health || 0) + delta));
await character.update({ health: next }, { transaction: t }); await character.update({ health: next }, { transaction: t });
} }
} else if (chosen === 'regional_festival') { } else if (chosen === 'regional_festival' || chosen === 'regional_storm' || chosen === 'regional_epidemic' || chosen === 'earthquake') {
const regionId = character?.regionId || falukantUser?.mainBranchRegionId || null; const regionId = character?.regionId || falukantUser?.mainBranchRegionId || null;
if (regionId) { if (regionId) {
const region = await RegionData.findByPk(regionId, { attributes: ['name'], transaction: t }); const region = await RegionData.findByPk(regionId, { attributes: ['name'], transaction: t });
payload.regionName = region?.name || null; payload.regionName = region?.name || null;
} }
// 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
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
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
payload.healthChange = `${delta}`;
const next = Math.min(100, Math.max(0, Number(character.health || 0) + delta));
await character.update({ health: next }, { transaction: t });
}
} }
// Store notification as JSON string so frontend can interpolate params // Store notification as JSON string so frontend can interpolate params
@@ -2955,7 +2981,7 @@ class FalukantService extends BaseService {
// Hole zufällige Charaktere aus der Hauptregion, die 10-14 Jahre alt sind // Hole zufällige Charaktere aus der Hauptregion, die 10-14 Jahre alt sind
// und keinen userId haben (also noch keinem User zugeordnet sind) // und keinen userId haben (also noch keinem User zugeordnet sind)
// und den noncivil Titel haben // und den noncivil Titel haben
const potentialHeirs = await FalukantCharacter.findAll({ let potentialHeirs = await FalukantCharacter.findAll({
where: { where: {
regionId: user.mainBranchRegionId, regionId: user.mainBranchRegionId,
userId: null, userId: null,
@@ -2972,6 +2998,62 @@ class FalukantService extends BaseService {
limit: 5 limit: 5
}); });
// Wenn keine Charaktere gefunden wurden, erstelle 5 neue
if (potentialHeirs.length === 0) {
const genders = ['male', 'female'];
const createdHeirs = [];
for (let i = 0; i < 5; i++) {
// Zufälliges Geschlecht
const gender = genders[Math.floor(Math.random() * genders.length)];
// Zufälliger Vorname für das Geschlecht
const firstName = await this.randomFirstName(gender);
let fnObj = await FalukantPredefineFirstname.findOne({ where: { name: firstName, gender } });
if (!fnObj) {
fnObj = await FalukantPredefineFirstname.create({ name: firstName, gender });
}
// Zufälliger Nachname
const lastName = await this.randomLastName();
let lnObj = await FalukantPredefineLastname.findOne({ where: { name: lastName } });
if (!lnObj) {
lnObj = await FalukantPredefineLastname.create({ name: lastName });
}
// Zufälliges Alter zwischen 10 und 14 Jahren (in Tagen)
const randomAge = Math.floor(Math.random() * 5) + 10; // 10-14
const birthdate = new Date(now);
birthdate.setDate(birthdate.getDate() - randomAge);
// Erstelle den Charakter
const newCharacter = await FalukantCharacter.create({
userId: null, // Wichtig: noch keinem User zugeordnet
regionId: user.mainBranchRegionId,
firstName: fnObj.id,
lastName: lnObj.id,
gender: gender,
birthdate: birthdate,
titleOfNobility: noncivilTitle.id,
health: 100,
moodId: 1
});
// Lade die Namen für die Rückgabe
const heirWithNames = await FalukantCharacter.findOne({
where: { id: newCharacter.id },
include: [
{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] },
{ model: FalukantPredefineLastname, as: 'definedLastName', attributes: ['name'] }
]
});
createdHeirs.push(heirWithNames);
}
potentialHeirs = createdHeirs;
}
// Berechne das Alter für jeden Charakter // Berechne das Alter für jeden Charakter
return potentialHeirs.map(heir => { return potentialHeirs.map(heir => {
const age = calcAge(heir.birthdate); const age = calcAge(heir.birthdate);