Implement inheritance logic for player characters in EventsWorker: Added functionality to handle character inheritance before deleting child relations. This includes querying for the user ID, determining the heir, and updating the heir's assets accordingly. Enhanced logging for inheritance events to improve traceability.
This commit is contained in:
@@ -1482,7 +1482,29 @@ impl EventsWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) Child-Relations löschen und Eltern benachrichtigen
|
// 3) Erben-Logik für Spieler-Charaktere (VOR dem Löschen der Child-Relations!)
|
||||||
|
// Prüfe, ob der Charakter ein Spieler-Charakter ist
|
||||||
|
const QUERY_GET_USER_ID: &str = r#"
|
||||||
|
SELECT user_id
|
||||||
|
FROM falukant_data.character
|
||||||
|
WHERE id = $1;
|
||||||
|
"#;
|
||||||
|
|
||||||
|
conn.prepare("get_user_id", QUERY_GET_USER_ID)?;
|
||||||
|
let user_rows = conn.execute("get_user_id", &[&character_id])?;
|
||||||
|
|
||||||
|
let user_id: Option<i32> = user_rows
|
||||||
|
.get(0)
|
||||||
|
.and_then(|r| r.get("user_id"))
|
||||||
|
.and_then(|v| v.parse::<i32>().ok());
|
||||||
|
|
||||||
|
if let Some(falukant_user_id) = user_id {
|
||||||
|
// Spieler-Charakter: Erben-Logik ausführen
|
||||||
|
// WICHTIG: Dies muss VOR dem Löschen der Child-Relations passieren!
|
||||||
|
Self::handle_inheritance(pool, broker, &mut conn, character_id, falukant_user_id)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4) Child-Relations löschen und Eltern benachrichtigen
|
||||||
const QUERY_DELETE_CHILD_RELATION: &str = r#"
|
const QUERY_DELETE_CHILD_RELATION: &str = r#"
|
||||||
WITH deleted AS (
|
WITH deleted AS (
|
||||||
DELETE FROM falukant_data.child_relation
|
DELETE FROM falukant_data.child_relation
|
||||||
@@ -1518,7 +1540,7 @@ impl EventsWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4) Charakter löschen
|
// 5) Charakter löschen
|
||||||
const QUERY_DELETE_CHARACTER: &str = r#"
|
const QUERY_DELETE_CHARACTER: &str = r#"
|
||||||
DELETE FROM falukant_data.character
|
DELETE FROM falukant_data.character
|
||||||
WHERE id = $1;
|
WHERE id = $1;
|
||||||
@@ -1530,6 +1552,184 @@ impl EventsWorker {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_inheritance(
|
||||||
|
pool: &ConnectionPool,
|
||||||
|
broker: &MessageBroker,
|
||||||
|
conn: &mut DbConnection,
|
||||||
|
deceased_character_id: i32,
|
||||||
|
falukant_user_id: i32,
|
||||||
|
) -> Result<(), DbError> {
|
||||||
|
// 1) Finde den Erben (bevorzugt is_heir = TRUE)
|
||||||
|
const QUERY_GET_HEIR: &str = r#"
|
||||||
|
SELECT child_character_id
|
||||||
|
FROM falukant_data.child_relation
|
||||||
|
WHERE father_character_id = $1
|
||||||
|
OR mother_character_id = $1
|
||||||
|
ORDER BY (is_heir IS TRUE) DESC,
|
||||||
|
updated_at DESC
|
||||||
|
LIMIT 1;
|
||||||
|
"#;
|
||||||
|
|
||||||
|
conn.prepare("get_heir", QUERY_GET_HEIR)?;
|
||||||
|
let heir_rows = conn.execute("get_heir", &[&deceased_character_id])?;
|
||||||
|
|
||||||
|
let heir_id: Option<i32> = heir_rows
|
||||||
|
.get(0)
|
||||||
|
.and_then(|r| r.get("child_character_id"))
|
||||||
|
.and_then(|v| v.parse::<i32>().ok());
|
||||||
|
|
||||||
|
let heir_id = match heir_id {
|
||||||
|
Some(id) if id > 0 => id,
|
||||||
|
_ => {
|
||||||
|
// Kein Erbe gefunden - Vermögen geht verloren
|
||||||
|
eprintln!(
|
||||||
|
"[EventsWorker] Kein Erbe für Charakter {} gefunden, Vermögen geht verloren",
|
||||||
|
deceased_character_id
|
||||||
|
);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2) Setze den Erben als neuen Spieler-Charakter
|
||||||
|
const QUERY_SET_CHARACTER_USER: &str = r#"
|
||||||
|
UPDATE falukant_data.character
|
||||||
|
SET user_id = $1,
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE id = $2;
|
||||||
|
"#;
|
||||||
|
|
||||||
|
conn.prepare("set_character_user", QUERY_SET_CHARACTER_USER)?;
|
||||||
|
conn.execute("set_character_user", &[&falukant_user_id, &heir_id])?;
|
||||||
|
|
||||||
|
// 3) Berechne das neue Vermögen basierend auf dem gesamten Vermögen
|
||||||
|
// Hole alle Vermögenswerte (analog zu UserCharacterWorker::calculate_new_money)
|
||||||
|
const QUERY_GET_CURRENT_MONEY: &str = r#"
|
||||||
|
SELECT money
|
||||||
|
FROM falukant_data.falukant_user
|
||||||
|
WHERE id = $1;
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const QUERY_GET_HOUSE_VALUE: &str = r#"
|
||||||
|
SELECT COALESCE(SUM(h.cost), 0) AS sum
|
||||||
|
FROM falukant_data.user_house AS uh
|
||||||
|
JOIN falukant_type.house AS h ON uh.house_type_id = h.id
|
||||||
|
WHERE uh.user_id = $1;
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const QUERY_GET_SETTLEMENT_VALUE: &str = r#"
|
||||||
|
SELECT COALESCE(SUM(b.base_cost), 0) AS sum
|
||||||
|
FROM falukant_data.branch AS br
|
||||||
|
JOIN falukant_type.branch AS b ON br.branch_type_id = b.id
|
||||||
|
WHERE br.falukant_user_id = $1;
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const QUERY_GET_INVENTORY_VALUE: &str = r#"
|
||||||
|
SELECT COALESCE(SUM(i.quantity * p.sell_cost), 0) AS sum
|
||||||
|
FROM falukant_data.inventory AS i
|
||||||
|
JOIN falukant_type.product AS p ON i.product_id = p.id
|
||||||
|
JOIN falukant_data.stock AS s ON i.stock_id = s.id
|
||||||
|
JOIN falukant_data.branch AS br ON s.branch_id = br.id
|
||||||
|
WHERE br.falukant_user_id = $1;
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const QUERY_GET_CREDIT_DEBT: &str = r#"
|
||||||
|
SELECT COALESCE(SUM(remaining_amount), 0) AS sum
|
||||||
|
FROM falukant_data.credit
|
||||||
|
WHERE falukant_user_id = $1;
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const QUERY_COUNT_CHILDREN: &str = r#"
|
||||||
|
SELECT COUNT(*) AS cnt
|
||||||
|
FROM falukant_data.child_relation
|
||||||
|
WHERE (father_character_id = $1 OR mother_character_id = $1)
|
||||||
|
AND child_character_id != $2;
|
||||||
|
"#;
|
||||||
|
|
||||||
|
conn.prepare("get_current_money", QUERY_GET_CURRENT_MONEY)?;
|
||||||
|
conn.prepare("get_house_value", QUERY_GET_HOUSE_VALUE)?;
|
||||||
|
conn.prepare("get_settlement_value", QUERY_GET_SETTLEMENT_VALUE)?;
|
||||||
|
conn.prepare("get_inventory_value", QUERY_GET_INVENTORY_VALUE)?;
|
||||||
|
conn.prepare("get_credit_debt", QUERY_GET_CREDIT_DEBT)?;
|
||||||
|
conn.prepare("count_children", QUERY_COUNT_CHILDREN)?;
|
||||||
|
|
||||||
|
let cash: f64 = conn
|
||||||
|
.execute("get_current_money", &[&falukant_user_id])?
|
||||||
|
.get(0)
|
||||||
|
.and_then(|r| r.get("money"))
|
||||||
|
.and_then(|v| v.parse::<f64>().ok())
|
||||||
|
.unwrap_or(0.0);
|
||||||
|
|
||||||
|
let houses: f64 = conn
|
||||||
|
.execute("get_house_value", &[&falukant_user_id])?
|
||||||
|
.get(0)
|
||||||
|
.and_then(|r| r.get("sum"))
|
||||||
|
.and_then(|v| v.parse::<f64>().ok())
|
||||||
|
.unwrap_or(0.0);
|
||||||
|
|
||||||
|
let settlements: f64 = conn
|
||||||
|
.execute("get_settlement_value", &[&falukant_user_id])?
|
||||||
|
.get(0)
|
||||||
|
.and_then(|r| r.get("sum"))
|
||||||
|
.and_then(|v| v.parse::<f64>().ok())
|
||||||
|
.unwrap_or(0.0);
|
||||||
|
|
||||||
|
let inventory: f64 = conn
|
||||||
|
.execute("get_inventory_value", &[&falukant_user_id])?
|
||||||
|
.get(0)
|
||||||
|
.and_then(|r| r.get("sum"))
|
||||||
|
.and_then(|v| v.parse::<f64>().ok())
|
||||||
|
.unwrap_or(0.0);
|
||||||
|
|
||||||
|
let debt: f64 = conn
|
||||||
|
.execute("get_credit_debt", &[&falukant_user_id])?
|
||||||
|
.get(0)
|
||||||
|
.and_then(|r| r.get("sum"))
|
||||||
|
.and_then(|v| v.parse::<f64>().ok())
|
||||||
|
.unwrap_or(0.0);
|
||||||
|
|
||||||
|
let child_count: i32 = conn
|
||||||
|
.execute("count_children", &[&deceased_character_id, &heir_id])?
|
||||||
|
.get(0)
|
||||||
|
.and_then(|r| r.get("cnt"))
|
||||||
|
.and_then(|v| v.parse::<i32>().ok())
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
// Berechne das neue Vermögen (analog zu UserCharacterWorker::calculate_new_money)
|
||||||
|
let total_assets = cash + houses + settlements + inventory - debt;
|
||||||
|
let single = child_count <= 0; // Nur der Erbe bleibt
|
||||||
|
|
||||||
|
let heir_share = if single {
|
||||||
|
total_assets
|
||||||
|
} else {
|
||||||
|
total_assets * 0.8
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_money = heir_share - (houses + settlements + inventory + debt);
|
||||||
|
let final_money = if new_money <= 1000.0 {
|
||||||
|
1000.0
|
||||||
|
} else {
|
||||||
|
new_money
|
||||||
|
};
|
||||||
|
|
||||||
|
// 4) Aktualisiere das Vermögen über die update_money Funktion
|
||||||
|
// Verwende die BaseWorker-Funktion für konsistente Geld-Updates
|
||||||
|
use crate::worker::base::BaseWorker;
|
||||||
|
let base = BaseWorker::new("EventsWorker", pool.clone(), broker.clone());
|
||||||
|
let money_change = final_money - cash;
|
||||||
|
base.change_falukant_user_money(
|
||||||
|
falukant_user_id,
|
||||||
|
money_change,
|
||||||
|
&format!("Erbe für Charakter {}", deceased_character_id),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
eprintln!(
|
||||||
|
"[EventsWorker] Erbe {} übernimmt Vermögen von Charakter {} (User {}): {:.2} (von {:.2} Gesamtvermögen, {} weitere Kinder)",
|
||||||
|
heir_id, deceased_character_id, falukant_user_id, final_money, total_assets, child_count
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn notify_user(
|
fn notify_user(
|
||||||
pool: &ConnectionPool,
|
pool: &ConnectionPool,
|
||||||
broker: &MessageBroker,
|
broker: &MessageBroker,
|
||||||
|
|||||||
Reference in New Issue
Block a user