Enhance marriage pregnancy management in SQL and UserCharacterWorker: Added a new query to clear stale marriage pregnancy records after 30 days. Updated existing queries to include shared children count for more accurate pregnancy probability calculations. Refactored logic in maybe_run_hourly_pregnancies to incorporate the new query and improved documentation for clarity on marriage pregnancy mechanics.
This commit is contained in:
@@ -1666,6 +1666,8 @@ pub const QUERY_AUTOBATISM: &str = r#"
|
||||
// Worker würfelt stündlich: P_stunde = 1 - (1 - P_jahr)^(1/8760), damit 24×/Tag zusammen
|
||||
// dieselbe kumulative Jahresaufteilung wie früher 1×/Tag mit P_tag = 1 - (1 - P_jahr)^(1/365).
|
||||
// Grenzen in Tagen: 1 Jahr ≈ 365 Tage (mother_age_days).
|
||||
// Erstes gemeinsames Kind (0 Zeilen in child_relation für dieses Paar): prob_year mindestens 1.0
|
||||
// im Alter 18–~44 (6570–16000 Tage), damit kinderlose Ehen nicht über viele Jahre ohne Nachwuchs bleiben.
|
||||
// WICHTIG: Vater/Mutter und Alter immer über gender ableiten — nicht character1/2 fest als Mutter!
|
||||
//
|
||||
// Ablauf Ehe: (1) Konzeption setzt `marriage_pregnancy_due_at` (+5 Tage), (2) Geburt wenn fällig.
|
||||
@@ -1705,6 +1707,14 @@ pub const QUERY_CLEAR_MARRIAGE_PREGNANCY_DUE: &str = r#"
|
||||
WHERE id = $1::int;
|
||||
"#;
|
||||
|
||||
/// Hängengebliebene Ehe-Schwangerschaft (Geburt fehlgeschlagen / inkonsistent): Flag nach 30 Tagen löschen.
|
||||
pub const QUERY_CLEAR_STALE_MARRIAGE_PREGNANCY_DUE: &str = r#"
|
||||
UPDATE falukant_data.relationship
|
||||
SET marriage_pregnancy_due_at = NULL
|
||||
WHERE marriage_pregnancy_due_at IS NOT NULL
|
||||
AND marriage_pregnancy_due_at < NOW() - INTERVAL '30 days';
|
||||
"#;
|
||||
|
||||
/// Stündlicher Konzeptionswurf (Ehe): bei Treffer wird `marriage_pregnancy_due_at` auf +5 Tage gesetzt.
|
||||
pub const QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE: &str = r#"
|
||||
WITH paired AS (
|
||||
@@ -1717,7 +1727,13 @@ pub const QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE: &str = r#"
|
||||
CASE WHEN c1.gender = 'male' THEN c1.region_id ELSE c2.region_id END AS region_id,
|
||||
CASE WHEN c1.gender = 'male' THEN fu1.id ELSE fu2.id END AS father_uid,
|
||||
CASE WHEN c1.gender = 'female' THEN fu1.id ELSE fu2.id END AS mother_uid,
|
||||
(CURRENT_DATE - c_female.birthdate::date)::int AS mother_age_days
|
||||
(CURRENT_DATE - c_female.birthdate::date)::int AS mother_age_days,
|
||||
(
|
||||
SELECT COUNT(*)::int
|
||||
FROM falukant_data.child_relation cr
|
||||
WHERE cr.father_character_id = (CASE WHEN c1.gender = 'male' THEN c1.id ELSE c2.id END)
|
||||
AND cr.mother_character_id = (CASE WHEN c1.gender = 'female' THEN c1.id ELSE c2.id END)
|
||||
) AS shared_children_count
|
||||
FROM falukant_data.relationship r
|
||||
JOIN falukant_type.relationship r2
|
||||
ON r2.id = r.relationship_type_id AND r2.tr = 'married'
|
||||
@@ -1743,6 +1759,7 @@ pub const QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE: &str = r#"
|
||||
p.father_uid,
|
||||
p.mother_uid,
|
||||
p.mother_age_days,
|
||||
p.shared_children_count,
|
||||
CASE
|
||||
WHEN p.mother_age_days < 4380 THEN 0.005
|
||||
WHEN p.mother_age_days < 4745 THEN 0.30
|
||||
@@ -1774,12 +1791,24 @@ pub const QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE: &str = r#"
|
||||
WHEN p.mother_age_days < 17520 THEN 0.015
|
||||
WHEN p.mother_age_days < 18250 THEN 0.005
|
||||
ELSE 0.001
|
||||
END AS prob_year
|
||||
END AS prob_year_raw
|
||||
FROM paired p
|
||||
),
|
||||
mother_age_final AS (
|
||||
SELECT
|
||||
ma.*,
|
||||
CASE
|
||||
WHEN ma.shared_children_count = 0
|
||||
AND ma.mother_age_days >= 6570
|
||||
AND ma.mother_age_days < 16000
|
||||
THEN GREATEST(ma.prob_year_raw, 1.0)
|
||||
ELSE ma.prob_year_raw
|
||||
END AS prob_year
|
||||
FROM mother_age ma
|
||||
),
|
||||
conceivable AS (
|
||||
SELECT ma.relationship_id
|
||||
FROM mother_age ma
|
||||
FROM mother_age_final ma
|
||||
WHERE ma.mother_age_days >= 4380
|
||||
AND ma.mother_age_days < 18993
|
||||
AND random() < (1 - POWER(1 - ma.prob_year, 1.0/8760.0))
|
||||
@@ -1811,7 +1840,13 @@ pub const QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES: &str = r#"
|
||||
CASE WHEN c1.gender = 'male' THEN c1.region_id ELSE c2.region_id END AS region_id,
|
||||
CASE WHEN c1.gender = 'male' THEN fu1.id ELSE fu2.id END AS father_uid,
|
||||
CASE WHEN c1.gender = 'female' THEN fu1.id ELSE fu2.id END AS mother_uid,
|
||||
(CURRENT_DATE - c_female.birthdate::date)::int AS mother_age_days
|
||||
(CURRENT_DATE - c_female.birthdate::date)::int AS mother_age_days,
|
||||
(
|
||||
SELECT COUNT(*)::int
|
||||
FROM falukant_data.child_relation cr
|
||||
WHERE cr.father_character_id = (CASE WHEN c1.gender = 'male' THEN c1.id ELSE c2.id END)
|
||||
AND cr.mother_character_id = (CASE WHEN c1.gender = 'female' THEN c1.id ELSE c2.id END)
|
||||
) AS shared_children_count
|
||||
FROM falukant_data.relationship r
|
||||
JOIN falukant_type.relationship r2
|
||||
ON r2.id = r.relationship_type_id AND r2.tr = 'married'
|
||||
@@ -1835,6 +1870,7 @@ pub const QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES: &str = r#"
|
||||
p.father_uid,
|
||||
p.mother_uid,
|
||||
p.mother_age_days,
|
||||
p.shared_children_count,
|
||||
CASE
|
||||
WHEN p.mother_age_days < 4380 THEN 0.005
|
||||
WHEN p.mother_age_days < 4745 THEN 0.30
|
||||
@@ -1866,8 +1902,20 @@ pub const QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES: &str = r#"
|
||||
WHEN p.mother_age_days < 17520 THEN 0.015
|
||||
WHEN p.mother_age_days < 18250 THEN 0.005
|
||||
ELSE 0.001
|
||||
END AS prob_year
|
||||
END AS prob_year_raw
|
||||
FROM paired p
|
||||
),
|
||||
mother_age_final AS (
|
||||
SELECT
|
||||
ma.*,
|
||||
CASE
|
||||
WHEN ma.shared_children_count = 0
|
||||
AND ma.mother_age_days >= 6570
|
||||
AND ma.mother_age_days < 16000
|
||||
THEN GREATEST(ma.prob_year_raw, 1.0)
|
||||
ELSE ma.prob_year_raw
|
||||
END AS prob_year
|
||||
FROM mother_age ma
|
||||
)
|
||||
SELECT
|
||||
father_cid,
|
||||
@@ -1879,7 +1927,7 @@ pub const QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES: &str = r#"
|
||||
mother_uid,
|
||||
mother_age_days,
|
||||
(1 - POWER(1 - prob_year, 1.0/8760.0)) * 100 AS prob_pct
|
||||
FROM mother_age
|
||||
FROM mother_age_final
|
||||
WHERE mother_age_days >= 4380
|
||||
AND mother_age_days < 18993
|
||||
AND random() < (1 - POWER(1 - prob_year, 1.0/8760.0));
|
||||
|
||||
@@ -33,7 +33,8 @@ use crate::worker::sql::{
|
||||
QUERY_UPDATE_USER_MONEY,
|
||||
QUERY_GET_FALUKANT_USER_ID,
|
||||
QUERY_AUTOBATISM,
|
||||
QUERY_CLEAR_MARRIAGE_PREGNANCY_DUE, QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES,
|
||||
QUERY_CLEAR_MARRIAGE_PREGNANCY_DUE, QUERY_CLEAR_STALE_MARRIAGE_PREGNANCY_DUE,
|
||||
QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES,
|
||||
QUERY_GET_MARRIAGE_BIRTH_DELIVERIES, QUERY_MARRIAGE_PREGNANCY_COLUMN_READY,
|
||||
QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE,
|
||||
QUERY_INSERT_CHILD,
|
||||
@@ -181,6 +182,7 @@ impl UserCharacterWorker {
|
||||
/// Ehe-Schwangerschaft: höchstens einmal pro Stunde (Daemon-Schleife ~1 s).
|
||||
/// Konzeption setzt `marriage_pregnancy_due_at` (+5 Tage); Geburt über `QUERY_GET_MARRIAGE_BIRTH_DELIVERIES`.
|
||||
/// Stündliche Zerlegung der Jahres-Wahrscheinlichkeit (`1/8760`), siehe `QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE`.
|
||||
/// Erstes gemeinsames Kind: Jahreswahrscheinlichkeit mindestens 1.0 (18–~44 J.), siehe `sql.rs`.
|
||||
fn maybe_run_hourly_pregnancies(&mut self) {
|
||||
let now = Instant::now();
|
||||
let should_run = match self.last_pregnancy_run {
|
||||
@@ -569,6 +571,9 @@ impl UserCharacterWorker {
|
||||
self.process_single_marriage_delivery(&mut conn, &row)?;
|
||||
}
|
||||
|
||||
conn.prepare("clear_stale_preg", QUERY_CLEAR_STALE_MARRIAGE_PREGNANCY_DUE)?;
|
||||
conn.execute("clear_stale_preg", &[])?;
|
||||
|
||||
conn.prepare("try_conception", QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE)?;
|
||||
conn.execute("try_conception", &[])?;
|
||||
} else {
|
||||
@@ -590,7 +595,7 @@ impl UserCharacterWorker {
|
||||
let relationship_id = parse_i32(row, "relationship_id", -1);
|
||||
let father_cid = parse_i32(row, "father_cid", -1);
|
||||
let mother_cid = parse_i32(row, "mother_cid", -1);
|
||||
if relationship_id < 0 || father_cid < 0 || mother_cid < 0 {
|
||||
if father_cid < 0 || mother_cid < 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user