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:
@@ -522,91 +522,18 @@ impl EventsWorker {
|
||||
max_percent,
|
||||
min_absolute_positive,
|
||||
} => {
|
||||
if effect_roll < *probability {
|
||||
let current_money =
|
||||
Self::get_current_money(&mut 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(
|
||||
&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
|
||||
}));
|
||||
if let Some(effect_json) = Self::handle_money_change_effect(
|
||||
&mut conn,
|
||||
event,
|
||||
user_id,
|
||||
effect_roll,
|
||||
*probability,
|
||||
*min_percent,
|
||||
*max_percent,
|
||||
min_absolute_positive,
|
||||
rng,
|
||||
)? {
|
||||
effect_results.push(effect_json);
|
||||
}
|
||||
}
|
||||
EventEffect::StorageCapacityChange {
|
||||
@@ -614,13 +541,16 @@ impl EventsWorker {
|
||||
min_percent,
|
||||
max_percent,
|
||||
} => {
|
||||
if effect_roll < *probability {
|
||||
let percent_change = rng.gen_range(*min_percent..=*max_percent);
|
||||
Self::apply_storage_capacity_change(&mut conn, user_id, percent_change)?;
|
||||
effect_results.push(json!({
|
||||
"type": "storage_capacity_change",
|
||||
"percent": percent_change
|
||||
}));
|
||||
if let Some(effect_json) = Self::handle_personal_storage_capacity_effect(
|
||||
&mut conn,
|
||||
user_id,
|
||||
effect_roll,
|
||||
*probability,
|
||||
*min_percent,
|
||||
*max_percent,
|
||||
rng,
|
||||
)? {
|
||||
effect_results.push(effect_json);
|
||||
}
|
||||
}
|
||||
EventEffect::CharacterHealthChange {
|
||||
@@ -628,32 +558,30 @@ impl EventsWorker {
|
||||
min_change,
|
||||
max_change,
|
||||
} => {
|
||||
if effect_roll < *probability
|
||||
&& let Ok((character_id, health_change)) = Self::apply_character_health_change(
|
||||
&mut conn,
|
||||
user_id,
|
||||
*min_change,
|
||||
*max_change,
|
||||
rng,
|
||||
pool,
|
||||
broker,
|
||||
)
|
||||
{
|
||||
effect_results.push(json!({
|
||||
"type": "character_health_change",
|
||||
"character_id": character_id,
|
||||
"change": health_change
|
||||
}));
|
||||
if let Some(effect_json) = Self::handle_personal_character_health_effect(
|
||||
&mut conn,
|
||||
user_id,
|
||||
effect_roll,
|
||||
*probability,
|
||||
*min_change,
|
||||
*max_change,
|
||||
rng,
|
||||
pool,
|
||||
broker,
|
||||
)? {
|
||||
effect_results.push(effect_json);
|
||||
}
|
||||
}
|
||||
EventEffect::CharacterDeath { probability } => {
|
||||
if effect_roll < *probability
|
||||
&& let Ok(character_id) = Self::apply_character_death(&mut conn, user_id, pool, broker)
|
||||
{
|
||||
effect_results.push(json!({
|
||||
"type": "character_death",
|
||||
"character_id": character_id
|
||||
}));
|
||||
if let Some(effect_json) = Self::handle_personal_character_death_effect(
|
||||
&mut conn,
|
||||
user_id,
|
||||
effect_roll,
|
||||
*probability,
|
||||
pool,
|
||||
broker,
|
||||
)? {
|
||||
effect_results.push(effect_json);
|
||||
}
|
||||
}
|
||||
EventEffect::StorageDamage {
|
||||
@@ -664,28 +592,19 @@ impl EventsWorker {
|
||||
storage_destruction_min_percent,
|
||||
storage_destruction_max_percent,
|
||||
} => {
|
||||
if effect_roll < *probability
|
||||
&& let Ok(damage_info) = Self::apply_personal_storage_damage(
|
||||
&mut conn,
|
||||
PersonalStorageDamageParams {
|
||||
user_id,
|
||||
stock_type_label,
|
||||
inventory_damage_min_percent: *inventory_damage_min_percent,
|
||||
inventory_damage_max_percent: *inventory_damage_max_percent,
|
||||
storage_destruction_min_percent: *storage_destruction_min_percent,
|
||||
storage_destruction_max_percent: *storage_destruction_max_percent,
|
||||
},
|
||||
rng,
|
||||
)
|
||||
{
|
||||
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,
|
||||
}));
|
||||
if let Some(effect_json) = Self::handle_personal_storage_damage_effect(
|
||||
&mut conn,
|
||||
user_id,
|
||||
stock_type_label,
|
||||
*probability,
|
||||
*inventory_damage_min_percent,
|
||||
*inventory_damage_max_percent,
|
||||
*storage_destruction_min_percent,
|
||||
*storage_destruction_max_percent,
|
||||
effect_roll,
|
||||
rng,
|
||||
)? {
|
||||
effect_results.push(effect_json);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@@ -960,28 +879,19 @@ impl EventsWorker {
|
||||
storage_destruction_min_percent,
|
||||
storage_destruction_max_percent,
|
||||
} => {
|
||||
if effect_roll < *probability
|
||||
&& let Ok(damage_info) = Self::apply_storage_damage(
|
||||
&mut conn,
|
||||
StorageDamageParams {
|
||||
region_id,
|
||||
stock_type_label,
|
||||
inventory_damage_min_percent: *inventory_damage_min_percent,
|
||||
inventory_damage_max_percent: *inventory_damage_max_percent,
|
||||
storage_destruction_min_percent: *storage_destruction_min_percent,
|
||||
storage_destruction_max_percent: *storage_destruction_max_percent,
|
||||
},
|
||||
rng,
|
||||
)
|
||||
{
|
||||
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,
|
||||
}));
|
||||
if let Some(effect_json) = Self::handle_regional_storage_damage_effect(
|
||||
&mut conn,
|
||||
region_id,
|
||||
stock_type_label,
|
||||
*probability,
|
||||
*inventory_damage_min_percent,
|
||||
*inventory_damage_max_percent,
|
||||
*storage_destruction_min_percent,
|
||||
*storage_destruction_max_percent,
|
||||
effect_roll,
|
||||
rng,
|
||||
)? {
|
||||
effect_results.push(effect_json);
|
||||
}
|
||||
}
|
||||
EventEffect::StorageCapacityChange {
|
||||
@@ -989,20 +899,16 @@ impl EventsWorker {
|
||||
min_percent,
|
||||
max_percent,
|
||||
} => {
|
||||
if effect_roll < *probability
|
||||
&& let Ok((affected_stocks, percent_change)) = Self::apply_regional_storage_capacity_change(
|
||||
&mut conn,
|
||||
region_id,
|
||||
*min_percent,
|
||||
*max_percent,
|
||||
rng,
|
||||
)
|
||||
{
|
||||
effect_results.push(json!({
|
||||
"type": "storage_capacity_change",
|
||||
"percent": percent_change,
|
||||
"affected_stocks": affected_stocks,
|
||||
}));
|
||||
if let Some(effect_json) = Self::handle_regional_storage_capacity_effect(
|
||||
&mut conn,
|
||||
region_id,
|
||||
effect_roll,
|
||||
*probability,
|
||||
*min_percent,
|
||||
*max_percent,
|
||||
rng,
|
||||
)? {
|
||||
effect_results.push(effect_json);
|
||||
}
|
||||
}
|
||||
EventEffect::HouseQualityChange {
|
||||
@@ -1010,20 +916,16 @@ impl EventsWorker {
|
||||
min_change,
|
||||
max_change,
|
||||
} => {
|
||||
if effect_roll < *probability
|
||||
&& let Ok((affected_houses, quality_change)) = Self::apply_regional_house_quality_change(
|
||||
&mut conn,
|
||||
region_id,
|
||||
*min_change,
|
||||
*max_change,
|
||||
rng,
|
||||
)
|
||||
{
|
||||
effect_results.push(json!({
|
||||
"type": "house_quality_change",
|
||||
"change": quality_change,
|
||||
"affected_houses": affected_houses,
|
||||
}));
|
||||
if let Some(effect_json) = Self::handle_regional_house_quality_effect(
|
||||
&mut conn,
|
||||
region_id,
|
||||
effect_roll,
|
||||
*probability,
|
||||
*min_change,
|
||||
*max_change,
|
||||
rng,
|
||||
)? {
|
||||
effect_results.push(effect_json);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@@ -1347,6 +1249,323 @@ impl EventsWorker {
|
||||
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(
|
||||
conn: &mut DbConnection,
|
||||
user_id: i32,
|
||||
|
||||
Reference in New Issue
Block a user