Add new event effects and implement regional changes: Introduced HouseQualityChange and updated StorageCapacityChange effects in EventsWorker. Implemented regional handling for storage capacity and house quality changes during events, enhancing gameplay dynamics and event impact. Improved logging for affected stocks and houses during changes.

This commit is contained in:
Torsten Schulz (local)
2025-12-08 11:23:34 +01:00
parent 5a3a818d84
commit 37b2c08555

View File

@@ -49,6 +49,8 @@ pub enum EventEffect {
storage_destruction_min_percent: f64, storage_destruction_min_percent: f64,
storage_destruction_max_percent: f64, storage_destruction_max_percent: f64,
}, },
/// Änderung der Hausqualität (in Punkten, kann negativ sein)
HouseQualityChange { probability: f64, min_change: i32, max_change: i32 },
} }
/// Definition eines zufälligen Ereignisses /// Definition eines zufälligen Ereignisses
@@ -154,6 +156,12 @@ impl EventsWorker {
storage_destruction_min_percent: 0.0, storage_destruction_min_percent: 0.0,
storage_destruction_max_percent: 10.0, storage_destruction_max_percent: 10.0,
}, },
// Verbleibende Lager können durch den Sturm beschädigt werden und Kapazität verlieren
EventEffect::StorageCapacityChange {
probability: 0.7, // 70% Chance, dass verbleibende Lager beschädigt werden
min_percent: -10.0,
max_percent: -3.0,
},
], ],
}, },
RandomEvent { RandomEvent {
@@ -200,9 +208,12 @@ impl EventsWorker {
storage_destruction_min_percent: 0.0, storage_destruction_min_percent: 0.0,
storage_destruction_max_percent: 50.0, storage_destruction_max_percent: 50.0,
}, },
// Für alle anderen Lagerarten: nur Lagerbestand kann zerstört werden // Verbleibende Lager können durch das Feuer beschädigt werden und Kapazität verlieren
// (storage_destruction_max_percent = 0.0 bedeutet keine Lager-Zerstörung) EventEffect::StorageCapacityChange {
// Hinweis: Weitere Stock-Typen können hier hinzugefügt werden probability: 0.8, // 80% Chance, dass verbleibende Lager beschädigt werden
min_percent: -15.0,
max_percent: -5.0,
},
], ],
}, },
RandomEvent { RandomEvent {
@@ -283,6 +294,33 @@ impl EventsWorker {
}, },
], ],
}, },
RandomEvent {
id: "earthquake".to_string(),
probability_per_minute: 0.001, // 0.1% pro Minute (sehr selten)
event_type: EventType::Regional,
title: "Erdbeben".to_string(),
description: "Ein Erdbeben hat die Region erschüttert.".to_string(),
effects: vec![
EventEffect::CharacterHealthChange {
probability: 0.3, // 30% Chance auf Gesundheitsschäden (geringe Wahrscheinlichkeit)
min_change: -20,
max_change: -5,
},
EventEffect::CharacterDeath {
probability: 0.05, // 5% Chance auf Tod (sehr geringe Wahrscheinlichkeit)
},
EventEffect::StorageCapacityChange {
probability: 1.0, // Alle Lager werden beschädigt
min_percent: -20.0,
max_percent: -5.0,
},
EventEffect::HouseQualityChange {
probability: 1.0, // Alle Häuser werden beschädigt
min_change: -15,
max_change: -5,
},
],
},
] ]
} }
@@ -782,6 +820,46 @@ impl EventsWorker {
} }
} }
} }
EventEffect::StorageCapacityChange {
probability,
min_percent,
max_percent,
} => {
if effect_roll < *probability {
if let Ok(affected_stocks) = Self::apply_regional_storage_capacity_change(
&mut conn,
region_id,
*min_percent,
*max_percent,
rng,
) {
effect_results.push(json!({
"type": "storage_capacity_change",
"affected_stocks": affected_stocks,
}));
}
}
}
EventEffect::HouseQualityChange {
probability,
min_change,
max_change,
} => {
if effect_roll < *probability {
if let Ok(affected_houses) = Self::apply_regional_house_quality_change(
&mut conn,
region_id,
*min_change,
*max_change,
rng,
) {
effect_results.push(json!({
"type": "house_quality_change",
"affected_houses": affected_houses,
}));
}
}
}
_ => { _ => {
eprintln!( eprintln!(
"[EventsWorker] Effekt {:?} wird für regionale Ereignisse noch nicht unterstützt", "[EventsWorker] Effekt {:?} wird für regionale Ereignisse noch nicht unterstützt",
@@ -856,19 +934,209 @@ impl EventsWorker {
} }
fn apply_storage_capacity_change( fn apply_storage_capacity_change(
_conn: &mut DbConnection, conn: &mut DbConnection,
user_id: i32, user_id: i32,
percent_change: f64, percent_change: f64,
) -> Result<(), DbError> { ) -> Result<(), DbError> {
// TODO: Implementierung für Lagerkapazitätsänderung // Hole alle Stocks des Spielers
// Dies könnte eine temporäre Modifikation sein oder eine permanente Änderung const QUERY_GET_USER_STOCKS: &str = r#"
SELECT s.id AS stock_id, s.quantity AS current_capacity
FROM falukant_data.stock s
JOIN falukant_data.branch b ON s.branch_id = b.id
WHERE b.falukant_user_id = $1;
"#;
conn.prepare("get_user_stocks_capacity", QUERY_GET_USER_STOCKS)?;
let stock_rows = conn.execute("get_user_stocks_capacity", &[&user_id])?;
if stock_rows.is_empty() {
eprintln!(
"[EventsWorker] Keine Stocks für Spieler {} gefunden",
user_id
);
return Ok(());
}
// Reduziere die Kapazität aller Stocks
const QUERY_UPDATE_STOCK_CAPACITY: &str = r#"
UPDATE falukant_data.stock
SET quantity = GREATEST(1, ROUND(quantity * (1 + $1 / 100.0)))
WHERE id = $2;
"#;
conn.prepare("update_stock_capacity", QUERY_UPDATE_STOCK_CAPACITY)?;
let mut affected_stocks = 0;
for row in stock_rows {
let stock_id: Option<i32> = row
.get("stock_id")
.and_then(|v| v.parse::<i32>().ok());
let stock_id = match stock_id {
Some(id) => id,
None => continue,
};
let current_capacity: i32 = row
.get("current_capacity")
.and_then(|v| v.parse::<i32>().ok())
.unwrap_or(0);
if current_capacity > 0 {
conn.execute("update_stock_capacity", &[&percent_change, &stock_id])?;
affected_stocks += 1;
}
}
eprintln!( eprintln!(
"[EventsWorker] Lagerkapazitätsänderung für Spieler {}: {:.2}% (noch nicht implementiert)", "[EventsWorker] Lagerkapazitätsänderung für Spieler {}: {:.2}% bei {} Stocks",
user_id, percent_change user_id, percent_change, affected_stocks
); );
Ok(()) Ok(())
} }
fn apply_regional_storage_capacity_change(
conn: &mut DbConnection,
region_id: i32,
min_percent: f64,
max_percent: f64,
rng: &mut impl Rng,
) -> Result<i32, DbError> {
// Hole alle Stocks in der Region
const QUERY_GET_REGION_STOCKS: &str = r#"
SELECT s.id AS stock_id, s.quantity AS current_capacity
FROM falukant_data.stock s
JOIN falukant_data.branch b ON s.branch_id = b.id
WHERE b.region_id = $1;
"#;
conn.prepare("get_region_stocks_capacity", QUERY_GET_REGION_STOCKS)?;
let stock_rows = conn.execute("get_region_stocks_capacity", &[&region_id])?;
if stock_rows.is_empty() {
eprintln!(
"[EventsWorker] Keine Stocks in Region {} gefunden",
region_id
);
return Ok(0);
}
// Berechne die prozentuale Änderung
let percent_change = rng.gen_range(min_percent..=max_percent);
// Reduziere die Kapazität aller Stocks
const QUERY_UPDATE_STOCK_CAPACITY_REGIONAL: &str = r#"
UPDATE falukant_data.stock
SET quantity = GREATEST(1, ROUND(quantity * (1 + $1 / 100.0)))
WHERE id = $2;
"#;
conn.prepare("update_stock_capacity_regional", QUERY_UPDATE_STOCK_CAPACITY_REGIONAL)?;
let mut affected_stocks = 0;
for row in stock_rows {
let stock_id: Option<i32> = row
.get("stock_id")
.and_then(|v| v.parse::<i32>().ok());
let stock_id = match stock_id {
Some(id) => id,
None => continue,
};
let current_capacity: i32 = row
.get("current_capacity")
.and_then(|v| v.parse::<i32>().ok())
.unwrap_or(0);
if current_capacity > 0 {
conn.execute("update_stock_capacity_regional", &[&percent_change, &stock_id])?;
affected_stocks += 1;
}
}
eprintln!(
"[EventsWorker] Regionale Lagerkapazitätsänderung für Region {}: {:.2}% bei {} Stocks",
region_id, percent_change, affected_stocks
);
Ok(affected_stocks)
}
fn apply_regional_house_quality_change(
conn: &mut DbConnection,
region_id: i32,
min_change: i32,
max_change: i32,
rng: &mut impl Rng,
) -> Result<i32, DbError> {
// Hole alle Häuser in der Region
const QUERY_GET_REGION_HOUSES: &str = r#"
SELECT uh.id AS house_id,
uh.roof_condition,
uh.floor_condition,
uh.wall_condition,
uh.window_condition
FROM falukant_data.user_house uh
JOIN falukant_data.character c ON c.user_id = uh.user_id
WHERE c.region_id = $1
AND uh.house_type_id NOT IN (
SELECT id
FROM falukant_type.house h
WHERE h.label_tr = 'under_bridge'
);
"#;
conn.prepare("get_region_houses", QUERY_GET_REGION_HOUSES)?;
let house_rows = conn.execute("get_region_houses", &[&region_id])?;
if house_rows.is_empty() {
eprintln!(
"[EventsWorker] Keine Häuser in Region {} gefunden",
region_id
);
return Ok(0);
}
// Berechne die Änderung
let quality_change = rng.gen_range(min_change..=max_change);
// Reduziere die Qualität aller Häuser
const QUERY_UPDATE_HOUSE_QUALITY: &str = r#"
UPDATE falukant_data.user_house
SET roof_condition = GREATEST(0, LEAST(100, roof_condition + $1)),
floor_condition = GREATEST(0, LEAST(100, floor_condition + $1)),
wall_condition = GREATEST(0, LEAST(100, wall_condition + $1)),
window_condition = GREATEST(0, LEAST(100, window_condition + $1))
WHERE id = $2;
"#;
conn.prepare("update_house_quality", QUERY_UPDATE_HOUSE_QUALITY)?;
let mut affected_houses = 0;
for row in house_rows {
let house_id: Option<i32> = row
.get("house_id")
.and_then(|v| v.parse::<i32>().ok());
let house_id = match house_id {
Some(id) => id,
None => continue,
};
conn.execute("update_house_quality", &[&quality_change, &house_id])?;
affected_houses += 1;
}
eprintln!(
"[EventsWorker] Regionale Hausqualitätsänderung für Region {}: {} Punkte bei {} Häusern",
region_id, quality_change, affected_houses
);
Ok(affected_houses)
}
fn apply_weather_change( fn apply_weather_change(
conn: &mut DbConnection, conn: &mut DbConnection,
region_id: i32, region_id: i32,