diff --git a/src/worker/events.rs b/src/worker/events.rs index aeff0eb..81b6e44 100644 --- a/src/worker/events.rs +++ b/src/worker/events.rs @@ -593,8 +593,10 @@ impl EventsWorker { max_change, } => { if effect_roll < *probability - && let Ok((character_id, health_change)) = Self::apply_character_health_change( + && let Ok((character_id, health_change, died)) = Self::apply_character_health_change( &mut conn, + pool, + broker, user_id, *min_change, *max_change, @@ -606,6 +608,12 @@ impl EventsWorker { "character_id": character_id, "change": health_change })); + if died { + effect_results.push(json!({ + "type": "character_death", + "character_id": character_id + })); + } } } EventEffect::CharacterDeath { probability } => { @@ -887,8 +895,10 @@ impl EventsWorker { } => { if effect_roll < *probability { // Für regionale Ereignisse: Betrifft alle Charaktere in der Region - if let Ok(affected_characters) = Self::apply_regional_character_health_change( + if let Ok((affected_characters, dead_characters)) = Self::apply_regional_character_health_change( &mut conn, + pool, + broker, region_id, *min_change, *max_change, @@ -899,6 +909,13 @@ impl EventsWorker { "affected_count": affected_characters.len(), "characters": affected_characters })); + if !dead_characters.is_empty() { + effect_results.push(json!({ + "type": "character_death", + "dead_count": dead_characters.len(), + "characters": dead_characters + })); + } } } } @@ -1320,11 +1337,13 @@ impl EventsWorker { fn apply_character_health_change( conn: &mut DbConnection, + pool: &ConnectionPool, + broker: &MessageBroker, user_id: i32, min_change: i32, max_change: i32, rng: &mut impl Rng, - ) -> Result<(i32, i32), DbError> { + ) -> Result<(i32, i32, bool), DbError> { // Hole einen zufälligen Charakter des Spielers conn.prepare("get_random_character", QUERY_GET_RANDOM_CHARACTER)?; let rows = conn.execute("get_random_character", &[&user_id])?; @@ -1355,7 +1374,15 @@ impl EventsWorker { conn.prepare("update_health", QUERY_UPDATE_HEALTH)?; conn.execute("update_health", &[&new_health, &character_id])?; - Ok((character_id, health_change)) + // Wenn die Gesundheit 0 erreicht, muss der Charakter „sterben“ (Cleanup + Löschen). + // Sonst bleibt er als health=0 „hängen“, weil spätere Queries meist health>0 filtern. + let died = new_health <= 0; + if died { + // Best-effort: Death-Handling kann fehlschlagen (FK/DB), dann loggt es selbst. + let _ = Self::handle_character_death(pool, broker, character_id); + } + + Ok((character_id, health_change, died)) } fn apply_character_death( @@ -1390,16 +1417,19 @@ impl EventsWorker { fn apply_regional_character_health_change( conn: &mut DbConnection, + pool: &ConnectionPool, + broker: &MessageBroker, region_id: i32, min_change: i32, max_change: i32, rng: &mut impl Rng, - ) -> Result, DbError> { + ) -> Result<(Vec<(i32, i32)>, Vec), DbError> { // Hole alle lebenden Charaktere in der Region conn.prepare("get_region_characters", QUERY_GET_REGION_CHARACTERS)?; let rows = conn.execute("get_region_characters", &[®ion_id])?; let mut affected_characters = Vec::new(); + let mut dead_characters = Vec::new(); for row in rows { let character_id: Option = row @@ -1424,9 +1454,15 @@ impl EventsWorker { conn.execute("update_health_regional", &[&new_health, &character_id])?; affected_characters.push((character_id, health_change)); + + if new_health <= 0 { + if Self::handle_character_death(pool, broker, character_id).is_ok() { + dead_characters.push(character_id); + } + } } - Ok(affected_characters) + Ok((affected_characters, dead_characters)) } fn apply_regional_character_death(