Add random heir fallback logic in EventsWorker: Implement a new SQL query to select a random NPC heir from the same region when no children are available. Enhance error handling to log cases where no heir is found, ensuring better user feedback and maintaining character associations. Update UserCharacterWorker to utilize this new logic for heir assignment.
This commit is contained in:
@@ -45,6 +45,7 @@ use crate::worker::sql::{
|
||||
QUERY_DELETE_CHILD_RELATION,
|
||||
QUERY_DELETE_CHARACTER,
|
||||
QUERY_GET_HEIR,
|
||||
QUERY_GET_RANDOM_HEIR_FROM_REGION,
|
||||
QUERY_SET_CHARACTER_USER,
|
||||
QUERY_CLEAR_CHARACTER_USER,
|
||||
QUERY_GET_CURRENT_MONEY,
|
||||
@@ -1589,17 +1590,27 @@ impl EventsWorker {
|
||||
.and_then(|r| r.get("child_character_id"))
|
||||
.and_then(|v| v.parse::<i32>().ok());
|
||||
|
||||
// Kein Kind als Erbe vorhanden? Dann fallback: zufälliger NPC-Character aus der Region,
|
||||
// Alter 10–14 Tage.
|
||||
let heir_id = match heir_id {
|
||||
Some(id) if id > 0 => id,
|
||||
_ => {
|
||||
// Kein Erbe gefunden - Vermögen geht verloren
|
||||
conn.prepare("random_heir_region", QUERY_GET_RANDOM_HEIR_FROM_REGION)?;
|
||||
let rows = conn.execute("random_heir_region", &[&deceased_character_id])?;
|
||||
rows.first()
|
||||
.and_then(|r| r.get("child_character_id"))
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
.unwrap_or(0)
|
||||
}
|
||||
};
|
||||
|
||||
if heir_id <= 0 {
|
||||
eprintln!(
|
||||
"[EventsWorker] Kein Erbe für Charakter {} gefunden, Vermögen geht verloren",
|
||||
deceased_character_id
|
||||
"[EventsWorker] Kein Erbe für Charakter {} gefunden (weder Kind noch Fallback in Region). User {} hat danach keinen Character.",
|
||||
deceased_character_id, falukant_user_id
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
// 2) Wichtig: erst die alte User-Zuordnung am verstorbenen Charakter lösen.
|
||||
// Falls es einen Unique-Constraint auf `character.user_id` gibt, würde das
|
||||
|
||||
@@ -1351,6 +1351,31 @@ pub const QUERY_RANDOM_HEIR: &str = r#"
|
||||
chosen.child_character_id;
|
||||
"#;
|
||||
|
||||
// Fallback-Erbe: Wenn ein Spieler-Character ohne Kinder stirbt, suchen wir einen zufälligen
|
||||
// NPC-Character in derselben Region (Alter 10–14 Tage) und übergeben ihm die user_id.
|
||||
pub const QUERY_GET_RANDOM_HEIR_FROM_REGION: &str = r#"
|
||||
SELECT ch.id AS child_character_id
|
||||
FROM falukant_data.character ch
|
||||
WHERE ch.user_id IS NULL
|
||||
AND ch.health > 0
|
||||
AND ch.id <> $1
|
||||
AND ch.region_id = (
|
||||
SELECT region_id
|
||||
FROM falukant_data.character
|
||||
WHERE id = $1
|
||||
)
|
||||
-- Alter zwischen 10 und 14 Tagen: birthdate in [now-14d, now-10d]
|
||||
AND ch.birthdate <= NOW() - INTERVAL '10 days'
|
||||
AND ch.birthdate >= NOW() - INTERVAL '14 days'
|
||||
AND ch.title_of_nobility = (
|
||||
SELECT id
|
||||
FROM falukant_type.title
|
||||
WHERE label_tr = 'noncivil'
|
||||
)
|
||||
ORDER BY RANDOM()
|
||||
LIMIT 1;
|
||||
"#;
|
||||
|
||||
pub const QUERY_UPDATE_USER_MONEY: &str = r#"
|
||||
UPDATE falukant_data.falukant_user
|
||||
SET money = $1,
|
||||
@@ -1600,8 +1625,16 @@ pub const QUERY_GET_FINISHED_PRODUCTIONS: &str = r#"
|
||||
ON p.product_id = pr.id
|
||||
JOIN falukant_data.branch br
|
||||
ON p.branch_id = br.id
|
||||
JOIN falukant_data.character c
|
||||
ON c.user_id = br.falukant_user_id
|
||||
-- Es kann vorkommen, dass ein User temporär keinen zugeordneten Character hat
|
||||
-- (z.B. nach Tod/Erbe). Produktionen sollen trotzdem abschließen.
|
||||
-- LATERAL verhindert Duplikate, falls ein User mehrere Characters hat.
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT c.id, c.user_id
|
||||
FROM falukant_data.character c
|
||||
WHERE c.user_id = br.falukant_user_id
|
||||
ORDER BY c.updated_at DESC NULLS LAST, c.id DESC
|
||||
LIMIT 1
|
||||
) c ON TRUE
|
||||
LEFT JOIN falukant_data.knowledge k
|
||||
ON p.product_id = k.product_id
|
||||
AND k.character_id = c.id
|
||||
|
||||
@@ -28,6 +28,7 @@ use crate::worker::sql::{
|
||||
QUERY_COUNT_CHILDREN,
|
||||
QUERY_GET_HEIR,
|
||||
QUERY_RANDOM_HEIR,
|
||||
QUERY_GET_RANDOM_HEIR_FROM_REGION,
|
||||
QUERY_SET_CHARACTER_USER,
|
||||
QUERY_CLEAR_CHARACTER_USER,
|
||||
QUERY_UPDATE_USER_MONEY,
|
||||
@@ -608,6 +609,12 @@ impl UserCharacterWorker {
|
||||
new_money = self.calculate_new_money(falukant_user_id, heir_id > 0)?;
|
||||
}
|
||||
|
||||
// Wenn es gar keine Kinder gibt, nimm einen zufälligen NPC in der Region (Alter 10–14 Tage).
|
||||
if heir_id < 1 {
|
||||
heir_id = self.get_random_heir_from_region(character_id)?;
|
||||
new_money = self.calculate_new_money(falukant_user_id, heir_id > 0)?;
|
||||
}
|
||||
|
||||
if heir_id > 0 {
|
||||
// Erst die alte Zuordnung lösen (Unique-Constraint safety), dann den Erben zuweisen.
|
||||
self.clear_character_user(character_id)?;
|
||||
@@ -669,6 +676,23 @@ impl UserCharacterWorker {
|
||||
.unwrap_or(-1))
|
||||
}
|
||||
|
||||
fn get_random_heir_from_region(&mut self, deceased_character_id: i32) -> Result<i32, DbError> {
|
||||
let mut conn = self
|
||||
.base
|
||||
.pool
|
||||
.get()
|
||||
.map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?;
|
||||
|
||||
conn.prepare("random_heir_region", QUERY_GET_RANDOM_HEIR_FROM_REGION)?;
|
||||
let rows = conn.execute("random_heir_region", &[&deceased_character_id])?;
|
||||
|
||||
Ok(rows
|
||||
.first()
|
||||
.and_then(|r| r.get("child_character_id"))
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
.unwrap_or(-1))
|
||||
}
|
||||
|
||||
fn set_new_character(
|
||||
&mut self,
|
||||
falukant_user_id: i32,
|
||||
|
||||
Reference in New Issue
Block a user