Nutze individuelles Fruchtbarkeitsalter für Schwangerschaften
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 4m42s

This commit is contained in:
Torsten Schulz (local)
2026-11-04 14:16:13 +01:00
parent ebb23787c3
commit 4fbb4d371c

View File

@@ -2175,10 +2175,8 @@ pub const QUERY_GET_MARRIAGE_BIRTH_DELIVERIES: &str = r#"
LEFT JOIN falukant_data.falukant_user fu2 ON fu2.id = c2.user_id LEFT JOIN falukant_data.falukant_user fu2 ON fu2.id = c2.user_id
WHERE r.marriage_pregnancy_due_at IS NOT NULL WHERE r.marriage_pregnancy_due_at IS NOT NULL
AND r.marriage_pregnancy_due_at <= NOW() AND r.marriage_pregnancy_due_at <= NOW()
-- Eine fällige automatische Ehe-Geburt bleibt vorgemerkt, bis beide -- Das Fruchtbarkeitsalter wird bei der Konzeption geprüft.
-- Eltern mindestens 16 Spieljahre (Kalendertage) alt sind. -- Bestehende Schwangerschaften werden durch Backfills nicht blockiert.
AND c1.birthdate <= CURRENT_DATE - INTERVAL '16 days'
AND c2.birthdate <= CURRENT_DATE - INTERVAL '16 days'
AND ((c1.gender = 'male' AND c2.gender = 'female') AND ((c1.gender = 'male' AND c2.gender = 'female')
OR (c1.gender = 'female' AND c2.gender = 'male')) OR (c1.gender = 'female' AND c2.gender = 'male'))
AND c_female.pregnancy_due_at IS NULL AND c_female.pregnancy_due_at IS NULL
@@ -2233,8 +2231,8 @@ pub const QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE: &str = r#"
LEFT JOIN falukant_data.falukant_user fu1 ON fu1.id = c1.user_id 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 LEFT JOIN falukant_data.falukant_user fu2 ON fu2.id = c2.user_id
WHERE r.marriage_pregnancy_due_at IS NULL WHERE r.marriage_pregnancy_due_at IS NULL
AND c1.birthdate <= CURRENT_DATE - INTERVAL '16 days' AND (CURRENT_DATE - c1.birthdate::date) >= c1.fertile_from_age
AND c2.birthdate <= CURRENT_DATE - INTERVAL '16 days' AND (CURRENT_DATE - c2.birthdate::date) >= c2.fertile_from_age
AND ((c1.gender = 'male' AND c2.gender = 'female') AND ((c1.gender = 'male' AND c2.gender = 'female')
OR (c1.gender = 'female' AND c2.gender = 'male')) OR (c1.gender = 'female' AND c2.gender = 'male'))
AND c_female.pregnancy_due_at IS NULL AND c_female.pregnancy_due_at IS NULL
@@ -2256,8 +2254,7 @@ pub const QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE: &str = r#"
conceivable AS ( conceivable AS (
SELECT ma.relationship_id SELECT ma.relationship_id
FROM mother_age ma FROM mother_age ma
WHERE ma.mother_age_days >= 16 WHERE random() < ma.prob_year
AND random() < ma.prob_year
) )
UPDATE falukant_data.relationship r UPDATE falukant_data.relationship r
SET marriage_pregnancy_due_at = NOW() + INTERVAL '18 hours' SET marriage_pregnancy_due_at = NOW() + INTERVAL '18 hours'
@@ -2304,8 +2301,8 @@ pub const QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES: &str = r#"
LEFT JOIN falukant_data.falukant_user fu2 ON fu2.id = c2.user_id LEFT JOIN falukant_data.falukant_user fu2 ON fu2.id = c2.user_id
WHERE ((c1.gender = 'male' AND c2.gender = 'female') WHERE ((c1.gender = 'male' AND c2.gender = 'female')
OR (c1.gender = 'female' AND c2.gender = 'male')) OR (c1.gender = 'female' AND c2.gender = 'male'))
AND c1.birthdate <= CURRENT_DATE - INTERVAL '16 days' AND (CURRENT_DATE - c1.birthdate::date) >= c1.fertile_from_age
AND c2.birthdate <= CURRENT_DATE - INTERVAL '16 days' AND (CURRENT_DATE - c2.birthdate::date) >= c2.fertile_from_age
AND c_female.pregnancy_due_at IS NULL AND c_female.pregnancy_due_at IS NULL
AND NOT EXISTS ( AND NOT EXISTS (
SELECT 1 SELECT 1
@@ -2338,8 +2335,7 @@ pub const QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES: &str = r#"
mother_age_days, mother_age_days,
prob_year * 100.0 AS prob_pct prob_year * 100.0 AS prob_pct
FROM mother_age FROM mother_age
WHERE mother_age_days >= 16 WHERE random() < prob_year;
AND random() < prob_year;
"#; "#;
/// Spalten `pregnancy_due_at` / `pregnancy_father_character_id` auf `character` (Migration `011_…`). /// Spalten `pregnancy_due_at` / `pregnancy_father_character_id` auf `character` (Migration `011_…`).
@@ -3945,8 +3941,8 @@ pub const QUERY_GET_LOVER_PREGNANCY_CANDIDATES: &str = r#"
-- `last_monthly_processed_at` wird im Familien-Tageslauf mitgeführt (1 Spieljahr = 1 Kalendertag). -- `last_monthly_processed_at` wird im Familien-Tageslauf mitgeführt (1 Spieljahr = 1 Kalendertag).
AND rs.last_monthly_processed_at IS NOT NULL AND rs.last_monthly_processed_at IS NOT NULL
AND rs.last_monthly_processed_at >= NOW() - INTERVAL '50 days' AND rs.last_monthly_processed_at >= NOW() - INTERVAL '50 days'
AND c1.birthdate <= CURRENT_DATE - INTERVAL '16 days' AND (CURRENT_DATE - c1.birthdate::date) >= c1.fertile_from_age
AND c2.birthdate <= CURRENT_DATE - INTERVAL '16 days' AND (CURRENT_DATE - c2.birthdate::date) >= c2.fertile_from_age
AND c_female.pregnancy_due_at IS NULL AND c_female.pregnancy_due_at IS NULL
AND NOT EXISTS ( AND NOT EXISTS (
SELECT 1 SELECT 1
@@ -3966,7 +3962,6 @@ pub const QUERY_GET_LOVER_PREGNANCY_CANDIDATES: &str = r#"
AND cr.created_at::date = CURRENT_DATE AND cr.created_at::date = CURRENT_DATE
) )
-- Ein Kalendertag entspricht einem Spieljahr (vgl. Ehe-Konzeption). -- Ein Kalendertag entspricht einem Spieljahr (vgl. Ehe-Konzeption).
AND (CURRENT_DATE - c_female.birthdate::date) >= 16
AND random() * 100.0 < ( AND random() * 100.0 < (
LEAST(12.0, GREATEST(0.0, LEAST(12.0, GREATEST(0.0,
CASE rs.lover_role CASE rs.lover_role
@@ -3991,12 +3986,12 @@ pub const QUERY_SET_CHARACTER_PREGNANCY_FROM_LOVER: &str = r#"
WHERE c_m.id = $1::int WHERE c_m.id = $1::int
AND c_m.health > 0 AND c_m.health > 0
AND c_m.pregnancy_due_at IS NULL AND c_m.pregnancy_due_at IS NULL
AND c_m.birthdate <= CURRENT_DATE - INTERVAL '16 days' AND (CURRENT_DATE - c_m.birthdate::date) >= c_m.fertile_from_age
AND EXISTS ( AND EXISTS (
SELECT 1 SELECT 1
FROM falukant_data.character c_f FROM falukant_data.character c_f
WHERE c_f.id = $2::int WHERE c_f.id = $2::int
AND c_f.birthdate <= CURRENT_DATE - INTERVAL '16 days' AND (CURRENT_DATE - c_f.birthdate::date) >= c_f.fertile_from_age
) )
AND NOT EXISTS ( AND NOT EXISTS (
SELECT 1 SELECT 1
@@ -4176,7 +4171,6 @@ mod tests {
use super::*; use super::*;
const AGE_14_GUARD: &str = "birthdate <= CURRENT_DATE - INTERVAL '14 days'"; const AGE_14_GUARD: &str = "birthdate <= CURRENT_DATE - INTERVAL '14 days'";
const AGE_16_GUARD: &str = "birthdate <= CURRENT_DATE - INTERVAL '16 days'";
#[test] #[test]
fn weddings_require_both_fiances_to_be_fourteen() { fn weddings_require_both_fiances_to_be_fourteen() {
@@ -4185,30 +4179,40 @@ mod tests {
} }
#[test] #[test]
fn automatic_pregnancy_paths_require_both_parents_to_be_sixteen() { fn automatic_conception_uses_each_parents_individual_fertility_age() {
for query in [ for query in [
QUERY_GET_MARRIAGE_BIRTH_DELIVERIES,
QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE, QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE,
QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES, QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES,
QUERY_GET_LOVER_PREGNANCY_CANDIDATES, QUERY_GET_LOVER_PREGNANCY_CANDIDATES,
] { ] {
assert_eq!(query.matches(AGE_16_GUARD).count(), 2, "{query}"); for parent in ["c1", "c2"] {
assert!(
query.contains(&format!(
"(CURRENT_DATE - {parent}.birthdate::date) >= {parent}.fertile_from_age"
)),
"{query}"
);
}
assert!(!query.contains("16 days"), "{query}");
assert!(!query.contains(">= 16"), "{query}");
assert!(!query.contains("5110"), "{query}");
}
for parent in ["c_m", "c_f"] {
assert!(QUERY_SET_CHARACTER_PREGNANCY_FROM_LOVER.contains(&format!(
"(CURRENT_DATE - {parent}.birthdate::date) >= {parent}.fertile_from_age"
)));
} }
assert!(QUERY_SET_CHARACTER_PREGNANCY_FROM_LOVER.contains(AGE_16_GUARD));
assert!(QUERY_GET_PLANNED_CHARACTER_BIRTH_DELIVERIES.contains("pregnancy_due_at <= NOW()"));
assert!(!QUERY_GET_PLANNED_CHARACTER_BIRTH_DELIVERIES.contains(AGE_16_GUARD));
} }
#[test] #[test]
fn automatic_conception_uses_game_years_not_real_world_days() { fn due_births_are_not_blocked_by_backfilled_fertility_ages() {
for query in [ for query in [
QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE, QUERY_GET_MARRIAGE_BIRTH_DELIVERIES,
QUERY_GET_LEGACY_MARRIAGE_INSTANT_PREGNANCY_CANDIDATES, QUERY_GET_PLANNED_CHARACTER_BIRTH_DELIVERIES,
QUERY_GET_LOVER_PREGNANCY_CANDIDATES,
] { ] {
assert!(!query.contains("5110"), "{query}"); assert!(!query.contains("fertile_from_age"));
assert!(query.contains(">= 16"), "{query}"); assert!(!query.contains("16 days"));
assert!(query.contains("<= NOW()"));
} }
} }