Enhance character health change handling in EventsWorker: Update health change functions to return character death status, allowing for better tracking of character deaths. Implement logging of character deaths in both individual and regional health change scenarios, improving event processing and state management.

This commit is contained in:
Torsten Schulz (local)
2025-12-23 14:20:41 +01:00
parent ade3bff5cf
commit da30ab0b15

View File

@@ -593,8 +593,10 @@ impl EventsWorker {
max_change, max_change,
} => { } => {
if effect_roll < *probability 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, &mut conn,
pool,
broker,
user_id, user_id,
*min_change, *min_change,
*max_change, *max_change,
@@ -606,6 +608,12 @@ impl EventsWorker {
"character_id": character_id, "character_id": character_id,
"change": health_change "change": health_change
})); }));
if died {
effect_results.push(json!({
"type": "character_death",
"character_id": character_id
}));
}
} }
} }
EventEffect::CharacterDeath { probability } => { EventEffect::CharacterDeath { probability } => {
@@ -887,8 +895,10 @@ impl EventsWorker {
} => { } => {
if effect_roll < *probability { if effect_roll < *probability {
// Für regionale Ereignisse: Betrifft alle Charaktere in der Region // 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, &mut conn,
pool,
broker,
region_id, region_id,
*min_change, *min_change,
*max_change, *max_change,
@@ -899,6 +909,13 @@ impl EventsWorker {
"affected_count": affected_characters.len(), "affected_count": affected_characters.len(),
"characters": affected_characters "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( fn apply_character_health_change(
conn: &mut DbConnection, conn: &mut DbConnection,
pool: &ConnectionPool,
broker: &MessageBroker,
user_id: i32, user_id: i32,
min_change: i32, min_change: i32,
max_change: i32, max_change: i32,
rng: &mut impl Rng, rng: &mut impl Rng,
) -> Result<(i32, i32), DbError> { ) -> Result<(i32, i32, bool), DbError> {
// Hole einen zufälligen Charakter des Spielers // Hole einen zufälligen Charakter des Spielers
conn.prepare("get_random_character", QUERY_GET_RANDOM_CHARACTER)?; conn.prepare("get_random_character", QUERY_GET_RANDOM_CHARACTER)?;
let rows = conn.execute("get_random_character", &[&user_id])?; let rows = conn.execute("get_random_character", &[&user_id])?;
@@ -1355,7 +1374,15 @@ impl EventsWorker {
conn.prepare("update_health", QUERY_UPDATE_HEALTH)?; conn.prepare("update_health", QUERY_UPDATE_HEALTH)?;
conn.execute("update_health", &[&new_health, &character_id])?; 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( fn apply_character_death(
@@ -1390,16 +1417,19 @@ impl EventsWorker {
fn apply_regional_character_health_change( fn apply_regional_character_health_change(
conn: &mut DbConnection, conn: &mut DbConnection,
pool: &ConnectionPool,
broker: &MessageBroker,
region_id: i32, region_id: i32,
min_change: i32, min_change: i32,
max_change: i32, max_change: i32,
rng: &mut impl Rng, rng: &mut impl Rng,
) -> Result<Vec<(i32, i32)>, DbError> { ) -> Result<(Vec<(i32, i32)>, Vec<i32>), DbError> {
// Hole alle lebenden Charaktere in der Region // Hole alle lebenden Charaktere in der Region
conn.prepare("get_region_characters", QUERY_GET_REGION_CHARACTERS)?; conn.prepare("get_region_characters", QUERY_GET_REGION_CHARACTERS)?;
let rows = conn.execute("get_region_characters", &[&region_id])?; let rows = conn.execute("get_region_characters", &[&region_id])?;
let mut affected_characters = Vec::new(); let mut affected_characters = Vec::new();
let mut dead_characters = Vec::new();
for row in rows { for row in rows {
let character_id: Option<i32> = row let character_id: Option<i32> = row
@@ -1424,9 +1454,15 @@ impl EventsWorker {
conn.execute("update_health_regional", &[&new_health, &character_id])?; conn.execute("update_health_regional", &[&new_health, &character_id])?;
affected_characters.push((character_id, health_change)); 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( fn apply_regional_character_death(