Refactor event handling in EventsWorker: Consolidated money change, storage capacity change, and character health change logic into dedicated methods for improved clarity and maintainability. This change enhances the handling of various event effects while preserving existing functionality.

This commit is contained in:
Torsten Schulz (local)
2026-03-10 22:04:54 +01:00
parent 9961b91c4f
commit 6757aa363f

View File

@@ -522,91 +522,18 @@ impl EventsWorker {
max_percent, max_percent,
min_absolute_positive, min_absolute_positive,
} => { } => {
if effect_roll < *probability { if let Some(effect_json) = Self::handle_money_change_effect(
let current_money = &mut conn,
Self::get_current_money(&mut conn, user_id).unwrap_or(0.0); event,
user_id,
// Spezialfall: Unerwarteter Geldsegen -> absoluter Zufallsbetrag 1..500 effect_roll,
if event.id == "windfall" { *probability,
let absolute_change: f64 = rng.gen_range(1.0..=500.0); *min_percent,
let percent_change = if current_money > 0.0 { *max_percent,
(absolute_change / current_money) * 100.0 min_absolute_positive,
} else { rng,
0.0 )? {
}; effect_results.push(effect_json);
let applied_change = Self::apply_money_change(
&mut conn,
user_id,
percent_change,
Some(absolute_change),
)
.unwrap_or(absolute_change);
effect_results.push(json!({
"type": "money_change",
"percent": percent_change,
"absolute": applied_change
}));
continue;
}
// Spezialfall: Diebstahl -> Verlust > 0, max. 90% und mind. 20 Geld übrig
if event.id == "theft" {
// Wenn kaum Geld vorhanden ist, passiert nichts
if current_money <= 20.0 {
continue;
}
let max_by_percent = current_money * 0.9;
let max_by_min_left = current_money - 20.0;
let max_loss = max_by_percent.min(max_by_min_left);
if max_loss < 1.0 {
continue;
}
let loss: f64 = rng.gen_range(1.0..=max_loss);
let percent_change = -(loss / current_money) * 100.0;
let absolute_change = -loss;
let applied_change = Self::apply_money_change(
&mut conn,
user_id,
percent_change,
Some(absolute_change),
)
.unwrap_or(absolute_change);
effect_results.push(json!({
"type": "money_change",
"percent": percent_change,
"absolute": applied_change
}));
continue;
}
// Standardfall: prozentuale Änderung, optional mit Mindestbetrag für positive Änderungen
let percent_change = rng.gen_range(*min_percent..=*max_percent);
let computed_change = current_money * (percent_change / 100.0);
let effective_change = match min_absolute_positive {
Some(min_abs) if percent_change > 0.0 && computed_change < *min_abs => {
*min_abs
}
_ => computed_change,
};
let absolute_change = Self::apply_money_change(
&mut conn,
user_id,
percent_change,
Some(effective_change),
)
.unwrap_or(effective_change);
effect_results.push(json!({
"type": "money_change",
"percent": percent_change,
"absolute": absolute_change
}));
} }
} }
EventEffect::StorageCapacityChange { EventEffect::StorageCapacityChange {
@@ -614,13 +541,16 @@ impl EventsWorker {
min_percent, min_percent,
max_percent, max_percent,
} => { } => {
if effect_roll < *probability { if let Some(effect_json) = Self::handle_personal_storage_capacity_effect(
let percent_change = rng.gen_range(*min_percent..=*max_percent); &mut conn,
Self::apply_storage_capacity_change(&mut conn, user_id, percent_change)?; user_id,
effect_results.push(json!({ effect_roll,
"type": "storage_capacity_change", *probability,
"percent": percent_change *min_percent,
})); *max_percent,
rng,
)? {
effect_results.push(effect_json);
} }
} }
EventEffect::CharacterHealthChange { EventEffect::CharacterHealthChange {
@@ -628,32 +558,30 @@ impl EventsWorker {
min_change, min_change,
max_change, max_change,
} => { } => {
if effect_roll < *probability if let Some(effect_json) = Self::handle_personal_character_health_effect(
&& let Ok((character_id, health_change)) = Self::apply_character_health_change( &mut conn,
&mut conn, user_id,
user_id, effect_roll,
*min_change, *probability,
*max_change, *min_change,
rng, *max_change,
pool, rng,
broker, pool,
) broker,
{ )? {
effect_results.push(json!({ effect_results.push(effect_json);
"type": "character_health_change",
"character_id": character_id,
"change": health_change
}));
} }
} }
EventEffect::CharacterDeath { probability } => { EventEffect::CharacterDeath { probability } => {
if effect_roll < *probability if let Some(effect_json) = Self::handle_personal_character_death_effect(
&& let Ok(character_id) = Self::apply_character_death(&mut conn, user_id, pool, broker) &mut conn,
{ user_id,
effect_results.push(json!({ effect_roll,
"type": "character_death", *probability,
"character_id": character_id pool,
})); broker,
)? {
effect_results.push(effect_json);
} }
} }
EventEffect::StorageDamage { EventEffect::StorageDamage {
@@ -664,28 +592,19 @@ impl EventsWorker {
storage_destruction_min_percent, storage_destruction_min_percent,
storage_destruction_max_percent, storage_destruction_max_percent,
} => { } => {
if effect_roll < *probability if let Some(effect_json) = Self::handle_personal_storage_damage_effect(
&& let Ok(damage_info) = Self::apply_personal_storage_damage( &mut conn,
&mut conn, user_id,
PersonalStorageDamageParams { stock_type_label,
user_id, *probability,
stock_type_label, *inventory_damage_min_percent,
inventory_damage_min_percent: *inventory_damage_min_percent, *inventory_damage_max_percent,
inventory_damage_max_percent: *inventory_damage_max_percent, *storage_destruction_min_percent,
storage_destruction_min_percent: *storage_destruction_min_percent, *storage_destruction_max_percent,
storage_destruction_max_percent: *storage_destruction_max_percent, effect_roll,
}, rng,
rng, )? {
) effect_results.push(effect_json);
{
effect_results.push(json!({
"type": "storage_damage",
"stock_type": stock_type_label,
"inventory_damage_percent": damage_info.inventory_damage_percent,
"storage_destruction_percent": damage_info.storage_destruction_percent,
"affected_stocks": damage_info.affected_stocks,
"destroyed_stocks": damage_info.destroyed_stocks,
}));
} }
} }
_ => { _ => {
@@ -960,28 +879,19 @@ impl EventsWorker {
storage_destruction_min_percent, storage_destruction_min_percent,
storage_destruction_max_percent, storage_destruction_max_percent,
} => { } => {
if effect_roll < *probability if let Some(effect_json) = Self::handle_regional_storage_damage_effect(
&& let Ok(damage_info) = Self::apply_storage_damage( &mut conn,
&mut conn, region_id,
StorageDamageParams { stock_type_label,
region_id, *probability,
stock_type_label, *inventory_damage_min_percent,
inventory_damage_min_percent: *inventory_damage_min_percent, *inventory_damage_max_percent,
inventory_damage_max_percent: *inventory_damage_max_percent, *storage_destruction_min_percent,
storage_destruction_min_percent: *storage_destruction_min_percent, *storage_destruction_max_percent,
storage_destruction_max_percent: *storage_destruction_max_percent, effect_roll,
}, rng,
rng, )? {
) effect_results.push(effect_json);
{
effect_results.push(json!({
"type": "storage_damage",
"stock_type": stock_type_label,
"inventory_damage_percent": damage_info.inventory_damage_percent,
"storage_destruction_percent": damage_info.storage_destruction_percent,
"affected_stocks": damage_info.affected_stocks,
"destroyed_stocks": damage_info.destroyed_stocks,
}));
} }
} }
EventEffect::StorageCapacityChange { EventEffect::StorageCapacityChange {
@@ -989,20 +899,16 @@ impl EventsWorker {
min_percent, min_percent,
max_percent, max_percent,
} => { } => {
if effect_roll < *probability if let Some(effect_json) = Self::handle_regional_storage_capacity_effect(
&& let Ok((affected_stocks, percent_change)) = Self::apply_regional_storage_capacity_change( &mut conn,
&mut conn, region_id,
region_id, effect_roll,
*min_percent, *probability,
*max_percent, *min_percent,
rng, *max_percent,
) rng,
{ )? {
effect_results.push(json!({ effect_results.push(effect_json);
"type": "storage_capacity_change",
"percent": percent_change,
"affected_stocks": affected_stocks,
}));
} }
} }
EventEffect::HouseQualityChange { EventEffect::HouseQualityChange {
@@ -1010,20 +916,16 @@ impl EventsWorker {
min_change, min_change,
max_change, max_change,
} => { } => {
if effect_roll < *probability if let Some(effect_json) = Self::handle_regional_house_quality_effect(
&& let Ok((affected_houses, quality_change)) = Self::apply_regional_house_quality_change( &mut conn,
&mut conn, region_id,
region_id, effect_roll,
*min_change, *probability,
*max_change, *min_change,
rng, *max_change,
) rng,
{ )? {
effect_results.push(json!({ effect_results.push(effect_json);
"type": "house_quality_change",
"change": quality_change,
"affected_houses": affected_houses,
}));
} }
} }
_ => { _ => {
@@ -1347,6 +1249,323 @@ impl EventsWorker {
Ok(()) Ok(())
} }
/// Behandelt Geldänderungen für persönliche Events (inkl. Spezialfälle „windfall“ und „theft“).
fn handle_money_change_effect(
conn: &mut DbConnection,
event: &RandomEvent,
user_id: i32,
effect_roll: f64,
probability: f64,
min_percent: f64,
max_percent: f64,
min_absolute_positive: &Option<f64>,
rng: &mut impl Rng,
) -> Result<Option<serde_json::Value>, DbError> {
if effect_roll >= probability {
return Ok(None);
}
let current_money = Self::get_current_money(conn, user_id).unwrap_or(0.0);
// Spezialfall: Unerwarteter Geldsegen -> absoluter Zufallsbetrag 1..500
if event.id == "windfall" {
let absolute_change: f64 = rng.gen_range(1.0..=500.0);
let percent_change = if current_money > 0.0 {
(absolute_change / current_money) * 100.0
} else {
0.0
};
let applied_change = Self::apply_money_change(
conn,
user_id,
percent_change,
Some(absolute_change),
)
.unwrap_or(absolute_change);
return Ok(Some(json!({
"type": "money_change",
"percent": percent_change,
"absolute": applied_change
})));
}
// Spezialfall: Diebstahl -> Verlust > 0, max. 90% und mind. 20 Geld übrig
if event.id == "theft" {
// Wenn kaum Geld vorhanden ist, passiert nichts
if current_money <= 20.0 {
return Ok(None);
}
let max_by_percent = current_money * 0.9;
let max_by_min_left = current_money - 20.0;
let max_loss = max_by_percent.min(max_by_min_left);
if max_loss < 1.0 {
return Ok(None);
}
let loss: f64 = rng.gen_range(1.0..=max_loss);
let percent_change = -(loss / current_money) * 100.0;
let absolute_change = -loss;
let applied_change = Self::apply_money_change(
conn,
user_id,
percent_change,
Some(absolute_change),
)
.unwrap_or(absolute_change);
return Ok(Some(json!({
"type": "money_change",
"percent": percent_change,
"absolute": applied_change
})));
}
// Standardfall: prozentuale Änderung, optional mit Mindestbetrag für positive Änderungen
let percent_change = rng.gen_range(min_percent..=max_percent);
let computed_change = current_money * (percent_change / 100.0);
let effective_change = match min_absolute_positive {
Some(min_abs) if percent_change > 0.0 && computed_change < *min_abs => *min_abs,
_ => computed_change,
};
let absolute_change = Self::apply_money_change(
conn,
user_id,
percent_change,
Some(effective_change),
)
.unwrap_or(effective_change);
Ok(Some(json!({
"type": "money_change",
"percent": percent_change,
"absolute": absolute_change
})))
}
/// Behandelt Lagerkapazitätsänderungen für persönliche Events.
fn handle_personal_storage_capacity_effect(
conn: &mut DbConnection,
user_id: i32,
effect_roll: f64,
probability: f64,
min_percent: f64,
max_percent: f64,
rng: &mut impl Rng,
) -> Result<Option<serde_json::Value>, DbError> {
if effect_roll >= probability {
return Ok(None);
}
let percent_change = rng.gen_range(min_percent..=max_percent);
Self::apply_storage_capacity_change(conn, user_id, percent_change)?;
Ok(Some(json!({
"type": "storage_capacity_change",
"percent": percent_change
})))
}
/// Behandelt Gesundheitsänderungen bei persönlichen Events.
fn handle_personal_character_health_effect(
conn: &mut DbConnection,
user_id: i32,
effect_roll: f64,
probability: f64,
min_change: i32,
max_change: i32,
rng: &mut impl Rng,
pool: &ConnectionPool,
broker: &MessageBroker,
) -> Result<Option<serde_json::Value>, DbError> {
if effect_roll >= probability {
return Ok(None);
}
if let Ok((character_id, health_change)) = Self::apply_character_health_change(
conn,
user_id,
min_change,
max_change,
rng,
pool,
broker,
) {
return Ok(Some(json!({
"type": "character_health_change",
"character_id": character_id,
"change": health_change
})));
}
Ok(None)
}
/// Behandelt Charakter-Tod bei persönlichen Events.
fn handle_personal_character_death_effect(
conn: &mut DbConnection,
user_id: i32,
effect_roll: f64,
probability: f64,
pool: &ConnectionPool,
broker: &MessageBroker,
) -> Result<Option<serde_json::Value>, DbError> {
if effect_roll >= probability {
return Ok(None);
}
if let Ok(character_id) = Self::apply_character_death(conn, user_id, pool, broker) {
return Ok(Some(json!({
"type": "character_death",
"character_id": character_id
})));
}
Ok(None)
}
/// Behandelt persönliche Lager-Schäden.
fn handle_personal_storage_damage_effect(
conn: &mut DbConnection,
user_id: i32,
stock_type_label: &str,
probability: f64,
inventory_damage_min_percent: f64,
inventory_damage_max_percent: f64,
storage_destruction_min_percent: f64,
storage_destruction_max_percent: f64,
effect_roll: f64,
rng: &mut impl Rng,
) -> Result<Option<serde_json::Value>, DbError> {
if effect_roll >= probability {
return Ok(None);
}
if let Ok(damage_info) = Self::apply_personal_storage_damage(
conn,
PersonalStorageDamageParams {
user_id,
stock_type_label,
inventory_damage_min_percent,
inventory_damage_max_percent,
storage_destruction_min_percent,
storage_destruction_max_percent,
},
rng,
) {
return Ok(Some(json!({
"type": "storage_damage",
"stock_type": stock_type_label,
"inventory_damage_percent": damage_info.inventory_damage_percent,
"storage_destruction_percent": damage_info.storage_destruction_percent,
"affected_stocks": damage_info.affected_stocks,
"destroyed_stocks": damage_info.destroyed_stocks,
})));
}
Ok(None)
}
/// Behandelt regionale Lager-Schäden.
fn handle_regional_storage_damage_effect(
conn: &mut DbConnection,
region_id: i32,
stock_type_label: &str,
probability: f64,
inventory_damage_min_percent: f64,
inventory_damage_max_percent: f64,
storage_destruction_min_percent: f64,
storage_destruction_max_percent: f64,
effect_roll: f64,
rng: &mut impl Rng,
) -> Result<Option<serde_json::Value>, DbError> {
if effect_roll >= probability {
return Ok(None);
}
if let Ok(damage_info) = Self::apply_storage_damage(
conn,
StorageDamageParams {
region_id,
stock_type_label,
inventory_damage_min_percent,
inventory_damage_max_percent,
storage_destruction_min_percent,
storage_destruction_max_percent,
},
rng,
) {
return Ok(Some(json!({
"type": "storage_damage",
"stock_type": stock_type_label,
"inventory_damage_percent": damage_info.inventory_damage_percent,
"storage_destruction_percent": damage_info.storage_destruction_percent,
"affected_stocks": damage_info.affected_stocks,
"destroyed_stocks": damage_info.destroyed_stocks,
})));
}
Ok(None)
}
/// Behandelt regionale Lagerkapazitätsänderungen.
fn handle_regional_storage_capacity_effect(
conn: &mut DbConnection,
region_id: i32,
effect_roll: f64,
probability: f64,
min_percent: f64,
max_percent: f64,
rng: &mut impl Rng,
) -> Result<Option<serde_json::Value>, DbError> {
if effect_roll >= probability {
return Ok(None);
}
if let Ok((affected_stocks, percent_change)) =
Self::apply_regional_storage_capacity_change(conn, region_id, min_percent, max_percent, rng)
{
return Ok(Some(json!({
"type": "storage_capacity_change",
"percent": percent_change,
"affected_stocks": affected_stocks,
})));
}
Ok(None)
}
/// Behandelt regionale Hausqualitätsänderungen.
fn handle_regional_house_quality_effect(
conn: &mut DbConnection,
region_id: i32,
effect_roll: f64,
probability: f64,
min_change: i32,
max_change: i32,
rng: &mut impl Rng,
) -> Result<Option<serde_json::Value>, DbError> {
if effect_roll >= probability {
return Ok(None);
}
if let Ok((affected_houses, quality_change)) =
Self::apply_regional_house_quality_change(conn, region_id, min_change, max_change, rng)
{
return Ok(Some(json!({
"type": "house_quality_change",
"change": quality_change,
"affected_houses": affected_houses,
})));
}
Ok(None)
}
fn apply_character_health_change( fn apply_character_health_change(
conn: &mut DbConnection, conn: &mut DbConnection,
user_id: i32, user_id: i32,