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,
} => {
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<Vec<(i32, i32)>, DbError> {
) -> Result<(Vec<(i32, i32)>, Vec<i32>), DbError> {
// Hole alle lebenden Charaktere in der Region
conn.prepare("get_region_characters", QUERY_GET_REGION_CHARACTERS)?;
let rows = conn.execute("get_region_characters", &[&region_id])?;
let mut affected_characters = Vec::new();
let mut dead_characters = Vec::new();
for row in rows {
let character_id: Option<i32> = 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(