diff --git a/src/worker/falukant_family.rs b/src/worker/falukant_family.rs index 2be6868..37ec680 100644 --- a/src/worker/falukant_family.rs +++ b/src/worker/falukant_family.rs @@ -22,6 +22,7 @@ use super::sql::{ QUERY_COUNT_LOVER_CHILDREN_FOR_USER, QUERY_FAMILY_SCHEMA_READY, QUERY_GET_ACTIVE_LOVER_ROWS_FOR_DAILY, QUERY_GET_ACTIVE_LOVER_ROWS_FOR_MONTHLY, QUERY_GET_ACTIVE_LOVER_ROWS_FOR_INSTALLMENT, QUERY_GET_LOVER_PREGNANCY_CANDIDATES, + QUERY_HAS_MOTHER_BIRTH_TODAY, QUERY_GET_MARRIAGE_ROWS, QUERY_GET_USER_HOUSE_ROW_BY_USER, QUERY_INSERT_CHILD, QUERY_INSERT_CHILD_RELATION_LOVER, QUERY_LOVER_BIRTH_PENALTY_MARRIAGE, QUERY_LOVER_BIRTH_PENALTY_REPUTATION, QUERY_LOVER_INSTALLMENT_SCHEMA_READY, @@ -1015,6 +1016,7 @@ impl FalukantFamilyWorker { conn.prepare("insert_child_rel_lover", QUERY_INSERT_CHILD_RELATION_LOVER)?; conn.prepare("pen_mar", QUERY_LOVER_BIRTH_PENALTY_MARRIAGE)?; conn.prepare("pen_rep", QUERY_LOVER_BIRTH_PENALTY_REPUTATION)?; + conn.prepare("has_mother_birth_today", QUERY_HAS_MOTHER_BIRTH_TODAY)?; for row in rows { let father_cid = parse_i32(&row, "father_cid", -1); @@ -1027,6 +1029,9 @@ impl FalukantFamilyWorker { let region_id = parse_i32(&row, "region_id", 0); let father_uid = parse_opt_i32(&row, "father_uid"); let mother_uid = parse_opt_i32(&row, "mother_uid"); + if mother_uid.is_some() && Self::mother_already_had_birth_today(&mut conn, mother_cid)? { + continue; + } let gender = if self.dist.sample(&mut self.rng) < 0.5 { "male" @@ -1073,6 +1078,18 @@ impl FalukantFamilyWorker { self.publish_falukant_update_family_and_status(user_id, "lover_birth"); } + fn mother_already_had_birth_today( + conn: &mut crate::db::DbConnection, + mother_character_id: i32, + ) -> Result { + let rows = conn.execute("has_mother_birth_today", &[&mother_character_id])?; + Ok(rows + .first() + .and_then(|r| r.get("has_birth_today")) + .map(|v| v == "t" || v == "true") + .unwrap_or(false)) + } + /// `falukantUpdateFamily` (mit `reason`) + `falukantUpdateStatus` — für UI-Refresh. fn publish_falukant_update_family_and_status(&self, user_id: i32, reason: &str) { let family = format!( diff --git a/src/worker/sql.rs b/src/worker/sql.rs index 00e4dad..1775397 100644 --- a/src/worker/sql.rs +++ b/src/worker/sql.rs @@ -3886,6 +3886,16 @@ pub const QUERY_INSERT_CHILD_RELATION_LOVER: &str = r#" ); "#; +/// Realismus-Regel: pro Mutter maximal eine Geburt pro Kalendertag. +pub const QUERY_HAS_MOTHER_BIRTH_TODAY: &str = r#" + SELECT EXISTS ( + SELECT 1 + FROM falukant_data.child_relation cr + WHERE cr.mother_character_id = $1::int + AND cr.created_at::date = CURRENT_DATE + ) AS has_birth_today; +"#; + // --- Produktionszertifikat (Daemon Daily, Spec: Produktionszertifikate) --- /// Ein Spielercharakter pro Falukant-User (bei mehreren lebenden: **höchste** `character.id`, diff --git a/src/worker/user_character.rs b/src/worker/user_character.rs index a371e2d..6e7100c 100644 --- a/src/worker/user_character.rs +++ b/src/worker/user_character.rs @@ -44,6 +44,7 @@ use crate::worker::sql::{ QUERY_INSERT_CHILD, QUERY_INSERT_CHILD_RELATION, QUERY_INSERT_CHILD_RELATION_PLANNED_BIRTH, + QUERY_HAS_MOTHER_BIRTH_TODAY, QUERY_INSERT_NOTIFICATION, QUERY_DELETE_DIRECTOR, QUERY_DELETE_RELATIONSHIP, @@ -569,6 +570,7 @@ impl UserCharacterWorker { conn.prepare("insert_child_relation", QUERY_INSERT_CHILD_RELATION)?; conn.prepare("insert_child_rel_planned", QUERY_INSERT_CHILD_RELATION_PLANNED_BIRTH)?; conn.prepare("clear_char_preg", QUERY_CLEAR_CHARACTER_PREGNANCY_AFTER_BIRTH)?; + conn.prepare("has_mother_birth_today", QUERY_HAS_MOTHER_BIRTH_TODAY)?; let use_gestation = self.marriage_pregnancy_column_ready.unwrap_or(false); let planned_pregnancy_ready = self.character_planned_pregnancy_columns_ready.unwrap_or(false); @@ -674,6 +676,9 @@ impl UserCharacterWorker { let father_uid = parse_opt_i32(row, "father_uid"); let mother_uid = parse_opt_i32(row, "mother_uid"); + if mother_uid.is_some() && mother_already_had_birth_today(conn, mother_cid)? { + return Ok(()); + } let birth_context = row .get("birth_context") @@ -732,6 +737,9 @@ impl UserCharacterWorker { let father_uid = parse_opt_i32(row, "father_uid"); let mother_uid = parse_opt_i32(row, "mother_uid"); + if mother_uid.is_some() && mother_already_had_birth_today(conn, mother_cid)? { + return Ok(()); + } let gender = if self.dist.sample(&mut self.rng) < 0.5 { "male" @@ -1193,6 +1201,18 @@ fn parse_opt_i32(row: &crate::db::Row, key: &str) -> Option { row.get(key).and_then(|v| v.parse::().ok()) } +fn mother_already_had_birth_today( + conn: &mut crate::db::DbConnection, + mother_character_id: i32, +) -> Result { + let rows = conn.execute("has_mother_birth_today", &[&mother_character_id])?; + Ok(rows + .first() + .and_then(|r| r.get("has_birth_today")) + .map(|v| v == "t" || v == "true") + .unwrap_or(false)) +} + #[derive(Debug, Clone)] struct Credit { amount: f64,