Implement marriage pregnancy management in UserCharacterWorker: Added SQL queries for handling marriage-related births and conception updates. Refactored pregnancy processing logic to accommodate new marriage pregnancy features, including checks for migration readiness and streamlined delivery processing. Enhanced documentation for clarity on marriage pregnancy mechanics.

This commit is contained in:
Torsten Schulz (local)
2026-03-25 11:56:25 +01:00
parent 083fa26297
commit 65772fb7de
4 changed files with 194 additions and 10 deletions

View File

@@ -1591,7 +1591,141 @@ pub const QUERY_AUTOBATISM: &str = r#"
// 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).
// WICHTIG: Vater/Mutter und Alter immer über gender ableiten — nicht character1/2 fest als Mutter!
pub const QUERY_GET_PREGNANCY_CANDIDATES: &str = r#"
//
// Ablauf Ehe: (1) Konzeption setzt `marriage_pregnancy_due_at` (+5 Tage), (2) Geburt wenn fällig.
// Migration: `008_falukant_marriage_pregnancy_due.sql`.
/// Fällige Geburten (Ehe): `marriage_pregnancy_due_at <= NOW()`.
pub const QUERY_GET_MARRIAGE_BIRTH_DELIVERIES: &str = r#"
SELECT
r.id AS relationship_id,
CASE WHEN c1.gender = 'male' THEN c1.id ELSE c2.id END AS father_cid,
CASE WHEN c1.gender = 'female' THEN c1.id ELSE c2.id END AS mother_cid,
CASE WHEN c1.gender = 'male' THEN c1.title_of_nobility ELSE c2.title_of_nobility END AS title_of_nobility,
CASE WHEN c1.gender = 'male' THEN c1.last_name ELSE c2.last_name END AS last_name,
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
FROM falukant_data.relationship r
JOIN falukant_type.relationship r2
ON r2.id = r.relationship_type_id AND r2.tr = 'married'
JOIN falukant_data.character c1 ON c1.id = r.character1_id
JOIN falukant_data.character c2 ON c2.id = r.character2_id
JOIN falukant_data.character c_female ON c_female.id = (
CASE WHEN c1.gender = 'female' THEN c1.id ELSE c2.id END
)
LEFT JOIN falukant_data.falukant_user fu1 ON fu1.id = c1.user_id
LEFT JOIN falukant_data.falukant_user fu2 ON fu2.id = c2.user_id
WHERE r.marriage_pregnancy_due_at IS NOT NULL
AND r.marriage_pregnancy_due_at <= NOW()
AND ((c1.gender = 'male' AND c2.gender = 'female')
OR (c1.gender = 'female' AND c2.gender = 'male'));
"#;
pub const QUERY_CLEAR_MARRIAGE_PREGNANCY_DUE: &str = r#"
UPDATE falukant_data.relationship
SET marriage_pregnancy_due_at = NULL
WHERE id = $1::int;
"#;
/// 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 (
SELECT
r.id AS relationship_id,
CASE WHEN c1.gender = 'male' THEN c1.id ELSE c2.id END AS father_cid,
CASE WHEN c1.gender = 'female' THEN c1.id ELSE c2.id END AS mother_cid,
CASE WHEN c1.gender = 'male' THEN c1.title_of_nobility ELSE c2.title_of_nobility END AS title_of_nobility,
CASE WHEN c1.gender = 'male' THEN c1.last_name ELSE c2.last_name END AS last_name,
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
FROM falukant_data.relationship r
JOIN falukant_type.relationship r2
ON r2.id = r.relationship_type_id AND r2.tr = 'married'
JOIN falukant_data.character c1 ON c1.id = r.character1_id
JOIN falukant_data.character c2 ON c2.id = r.character2_id
JOIN falukant_data.character c_female ON c_female.id = (
CASE WHEN c1.gender = 'female' THEN c1.id ELSE c2.id END
)
LEFT JOIN falukant_data.falukant_user fu1 ON fu1.id = c1.user_id
LEFT JOIN falukant_data.falukant_user fu2 ON fu2.id = c2.user_id
WHERE r.marriage_pregnancy_due_at IS NULL
AND ((c1.gender = 'male' AND c2.gender = 'female')
OR (c1.gender = 'female' AND c2.gender = 'male'))
),
mother_age AS (
SELECT
p.relationship_id,
p.father_cid,
p.mother_cid,
p.title_of_nobility,
p.last_name,
p.region_id,
p.father_uid,
p.mother_uid,
p.mother_age_days,
CASE
WHEN p.mother_age_days < 4380 THEN 0.005
WHEN p.mother_age_days < 4745 THEN 0.30
WHEN p.mother_age_days < 5110 THEN 0.45
WHEN p.mother_age_days < 5475 THEN 0.55
WHEN p.mother_age_days < 5840 THEN 0.60
WHEN p.mother_age_days < 6205 THEN 0.725
WHEN p.mother_age_days < 6570 THEN 0.80
WHEN p.mother_age_days < 7305 THEN 0.855
WHEN p.mother_age_days < 9125 THEN 0.875
WHEN p.mother_age_days < 10950 THEN 0.84
WHEN p.mother_age_days < 11315 THEN 0.785
WHEN p.mother_age_days < 11680 THEN 0.765
WHEN p.mother_age_days < 12045 THEN 0.74
WHEN p.mother_age_days < 12410 THEN 0.72
WHEN p.mother_age_days < 12775 THEN 0.695
WHEN p.mother_age_days < 13140 THEN 0.65
WHEN p.mother_age_days < 13505 THEN 0.63
WHEN p.mother_age_days < 13870 THEN 0.60
WHEN p.mother_age_days < 14235 THEN 0.55
WHEN p.mother_age_days < 14600 THEN 0.50
WHEN p.mother_age_days < 14965 THEN 0.45
WHEN p.mother_age_days < 15330 THEN 0.35
WHEN p.mother_age_days < 15695 THEN 0.25
WHEN p.mother_age_days < 16060 THEN 0.15
WHEN p.mother_age_days < 16425 THEN 0.075
WHEN p.mother_age_days < 16790 THEN 0.03
WHEN p.mother_age_days < 17155 THEN 0.02
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
FROM paired p
),
conceivable AS (
SELECT ma.relationship_id
FROM mother_age 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))
)
UPDATE falukant_data.relationship r
SET marriage_pregnancy_due_at = NOW() + INTERVAL '5 days'
FROM conceivable c
WHERE r.id = c.relationship_id;
"#;
pub const QUERY_MARRIAGE_PREGNANCY_COLUMN_READY: &str = r#"
SELECT EXISTS (
SELECT 1
FROM information_schema.columns
WHERE table_schema = 'falukant_data'
AND table_name = 'relationship'
AND column_name = 'marriage_pregnancy_due_at'
) AS ready;
"#;
/// Ehe: ohne Migration 008 — stündlicher Wurf legt sofort ein Kind an (wie früher).
pub const QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES: &str = r#"
WITH paired AS (
SELECT
CASE WHEN c1.gender = 'male' THEN c1.id ELSE c2.id END AS father_cid,
@@ -3059,7 +3193,7 @@ pub const QUERY_GET_LOVER_PREGNANCY_CANDIDATES: &str = r#"
AND rs.affection >= 45
AND rs.maintenance_level >= 30
AND rs.last_monthly_processed_at IS NOT NULL
AND date_trunc('month', rs.last_monthly_processed_at) = date_trunc('month', CURRENT_TIMESTAMP)
AND rs.last_monthly_processed_at >= NOW() - INTERVAL '50 days'
AND NOT EXISTS (
SELECT 1
FROM falukant_data.child_relation cr