Refactor event handling for character death: Updated the EventsWorker to ensure only player characters are notified of sudden child deaths, while NPCs are excluded. Adjusted health update logic to prevent player characters from reaching zero health due to accidents or illnesses. Enhanced SQL queries to filter characters based on user ID, improving clarity and functionality.

This commit is contained in:
Torsten Schulz (local)
2026-03-02 00:36:21 +01:00
parent 69dad6854a
commit 5d0dd41c3f
2 changed files with 51 additions and 46 deletions

View File

@@ -703,19 +703,12 @@ impl EventsWorker {
}
};
// Nur NPC-Kinder werden vom Kindstod getroffen; user_id ist bei NPCs None
let user_id: Option<i32> = rows
.first()
.and_then(|r| r.get("user_id"))
.and_then(|v| v.parse::<i32>().ok());
let user_id = match user_id {
Some(id) => id,
None => {
eprintln!("[EventsWorker] Kein user_id für Kind {} gefunden", character_id);
return Ok(());
}
};
// Wende Effekte an (in diesem Fall nur CharacterDeath)
let mut effect_results = Vec::new();
for effect in &event.effects {
@@ -740,32 +733,32 @@ impl EventsWorker {
}
}
// Schreibe Benachrichtigung in die Datenbank mit Event-Details
let notification_json = serde_json::json!({
"tr": format!("random_event.{}", event.id),
"event_id": event.id,
"event_type": "personal",
"character_id": character_id,
"effects": effect_results
});
Self::notify_user(pool, broker, user_id, &notification_json.to_string())?;
// Nur Spieler benachrichtigen (NPC-Kindstod hat keinen user_id)
if let Some(uid) = user_id {
let notification_json = serde_json::json!({
"tr": format!("random_event.{}", event.id),
"event_id": event.id,
"event_type": "personal",
"character_id": character_id,
"effects": effect_results
});
Self::notify_user(pool, broker, uid, &notification_json.to_string())?;
// Sende Benachrichtigung über WebSocket
let notification = json!({
"event": "random_event",
"event_id": event.id,
"event_type": "personal",
"user_id": user_id,
"character_id": character_id,
"title": event.title,
"description": event.description,
"effects": effect_results
});
broker.publish(notification.to_string());
let notification = json!({
"event": "random_event",
"event_id": event.id,
"event_type": "personal",
"user_id": uid,
"character_id": character_id,
"title": event.title,
"description": event.description,
"effects": effect_results
});
broker.publish(notification.to_string());
}
eprintln!(
"[EventsWorker] Plötzlicher Kindstod für Charakter {} (Spieler {}) verarbeitet",
character_id, user_id
"[EventsWorker] Plötzlicher Kindstod für Charakter {} verarbeitet",
character_id
);
Ok(())
@@ -1295,8 +1288,8 @@ impl EventsWorker {
min_change: i32,
max_change: i32,
rng: &mut impl Rng,
pool: &ConnectionPool,
broker: &MessageBroker,
_pool: &ConnectionPool,
_broker: &MessageBroker,
) -> Result<(i32, i32), DbError> {
// Hole einen zufälligen Charakter des Spielers
conn.prepare("get_random_character", QUERY_GET_RANDOM_CHARACTER)?;
@@ -1322,19 +1315,13 @@ impl EventsWorker {
.unwrap_or(100);
let health_change = rng.gen_range(min_change..=max_change);
let new_health = (current_health + health_change).clamp(0, 100);
// Durch Unfälle/Krankheiten soll Gesundheit von Spieler-Charakteren nicht auf 0 fallen
let new_health = (current_health + health_change).clamp(1, 100);
// Update Gesundheit
conn.prepare("update_health", QUERY_UPDATE_HEALTH)?;
conn.execute("update_health", &[&new_health, &character_id])?;
// Bei Health <= 0 sofort Tod prüfen und verarbeiten
if new_health <= 0 {
if let Err(e) = Self::handle_character_death(pool, broker, character_id) {
eprintln!("[EventsWorker] handle_character_death nach Health-Update: {e}");
}
}
Ok((character_id, health_change))
}
@@ -1400,7 +1387,16 @@ impl EventsWorker {
.unwrap_or(100);
let health_change = rng.gen_range(min_change..=max_change);
let new_health = (current_health + health_change).clamp(0, 100);
let user_id: Option<i32> = row
.get("user_id")
.and_then(|v| v.parse::<i32>().ok());
// Durch Unfälle/Krankheiten soll Gesundheit von Spieler-Charakteren nicht auf 0 fallen
let new_health_raw = (current_health + health_change).clamp(0, 100);
let new_health = if user_id.is_some() {
new_health_raw.max(1)
} else {
new_health_raw
};
// Update Gesundheit
conn.prepare("update_health_regional", QUERY_UPDATE_HEALTH)?;
@@ -1444,7 +1440,14 @@ impl EventsWorker {
None => continue,
};
// Verwende die existierende Logik zum Löschen von Charakteren
let user_id: Option<i32> = row
.get("user_id")
.and_then(|v| v.parse::<i32>().ok());
// Nur NPCs (user_id IS NULL) von regionalem Tod betroffen
if user_id.is_some() {
continue;
}
if Self::handle_character_death(pool, broker, character_id).is_ok() {
dead_characters.push(character_id);
}