Aktualisiere Logik zur Schwangerschaftsplanung: Ändere die Intervalle für die Schwangerschaftsplanung in den SQL-Abfragen auf 18 Stunden und entferne nicht benötigte Abfragen zur Geburt. Dies verbessert die Einhaltung der Regel, dass eine Mutter pro Kalendertag nur ein Kind gebären kann.
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 1m44s
All checks were successful
Deploy yourpart (blue-green) / deploy (push) Successful in 1m44s
This commit is contained in:
@@ -23,10 +23,9 @@ use super::sql::{
|
||||
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,
|
||||
QUERY_GET_MARRIAGE_ROWS, QUERY_GET_USER_HOUSE_ROW_BY_USER, QUERY_LOVER_INSTALLMENT_SCHEMA_READY,
|
||||
QUERY_MARK_LOVER_DAILY_DONE, QUERY_MARK_LOVER_INSTALLMENT_AT, QUERY_MARK_LOVER_MONTHLY_DONE,
|
||||
QUERY_SET_CHARACTER_PREGNANCY_FROM_LOVER,
|
||||
QUERY_MARRIAGE_SUBTRACT_SATISFACTION, QUERY_RESET_LOVER_UNDERPAY_COUNTERS,
|
||||
QUERY_UPDATE_CHARACTER_REPUTATION, QUERY_UPDATE_LOVER_UNDERPAY_STATE,
|
||||
QUERY_UPDATE_LOVER_VISIBILITY_DISCRETION, QUERY_UPDATE_MARRIAGE_STATE_AND_BUFFS,
|
||||
@@ -1010,12 +1009,9 @@ impl FalukantFamilyWorker {
|
||||
.map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?;
|
||||
|
||||
conn.prepare("lover_preg", QUERY_GET_LOVER_PREGNANCY_CANDIDATES)?;
|
||||
conn.prepare("set_lover_preg", QUERY_SET_CHARACTER_PREGNANCY_FROM_LOVER)?;
|
||||
let rows = conn.execute("lover_preg", &[])?;
|
||||
|
||||
conn.prepare("insert_child", QUERY_INSERT_CHILD)?;
|
||||
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 {
|
||||
@@ -1024,60 +1020,28 @@ impl FalukantFamilyWorker {
|
||||
if father_cid < 0 || mother_cid < 0 {
|
||||
continue;
|
||||
}
|
||||
let title_of_nobility = parse_i32(&row, "title_of_nobility", 0);
|
||||
let last_name = parse_i32(&row, "last_name", 0);
|
||||
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)? {
|
||||
if Self::mother_already_had_birth_today(&mut conn, mother_cid)? {
|
||||
continue;
|
||||
}
|
||||
|
||||
let gender = if self.dist.sample(&mut self.rng) < 0.5 {
|
||||
"male"
|
||||
} else {
|
||||
"female"
|
||||
};
|
||||
|
||||
let inserted =
|
||||
conn.execute("insert_child", &[®ion_id, &gender, &last_name, &title_of_nobility])?;
|
||||
let child_cid = inserted
|
||||
.first()
|
||||
.and_then(|r| r.get("child_cid"))
|
||||
.and_then(|v| v.parse::<i32>().ok())
|
||||
.unwrap_or(-1);
|
||||
if child_cid < 0 {
|
||||
let set_rows = conn.execute("set_lover_preg", &[&mother_cid, &father_cid])?;
|
||||
if set_rows.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
conn.execute(
|
||||
"insert_child_rel_lover",
|
||||
&[&father_cid, &mother_cid, &child_cid],
|
||||
)?;
|
||||
|
||||
conn.execute("pen_mar", &[&father_cid])?;
|
||||
conn.execute("pen_mar", &[&mother_cid])?;
|
||||
conn.execute("pen_rep", &[&father_cid])?;
|
||||
conn.execute("pen_rep", &[&mother_cid])?;
|
||||
|
||||
if let Some(uid) = father_uid {
|
||||
self.publish_children(uid);
|
||||
self.publish_falukant_update_family_and_status(uid, "lover_pregnancy");
|
||||
}
|
||||
if let Some(uid) = mother_uid {
|
||||
self.publish_children(uid);
|
||||
self.publish_falukant_update_family_and_status(uid, "lover_pregnancy");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn publish_children(&self, user_id: i32) {
|
||||
let children_update =
|
||||
format!(r#"{{"event":"children_update","user_id":{}}}"#, user_id);
|
||||
self.base.broker.publish(children_update);
|
||||
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,
|
||||
|
||||
@@ -2179,7 +2179,7 @@ pub const QUERY_AUTOBATISM: &str = r#"
|
||||
// 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.
|
||||
// Ablauf Ehe: (1) Konzeption setzt `marriage_pregnancy_due_at` (+18 Stunden), (2) Geburt wenn fällig.
|
||||
// Migration: `008_falukant_marriage_pregnancy_due.sql`.
|
||||
|
||||
/// Fällige Geburten (Ehe): `marriage_pregnancy_due_at <= NOW()`.
|
||||
@@ -2234,7 +2234,7 @@ pub const QUERY_CLEAR_STALE_MARRIAGE_PREGNANCY_DUE: &str = r#"
|
||||
AND marriage_pregnancy_due_at < NOW() - INTERVAL '30 days';
|
||||
"#;
|
||||
|
||||
/// Täglicher Konzeptionswurf (Ehe): bei Treffer wird `marriage_pregnancy_due_at` auf +5 Tage gesetzt.
|
||||
/// Täglicher Konzeptionswurf (Ehe): bei Treffer wird `marriage_pregnancy_due_at` auf +18 Stunden gesetzt.
|
||||
pub const QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE: &str = r#"
|
||||
WITH paired AS (
|
||||
SELECT
|
||||
@@ -2333,8 +2333,8 @@ pub const QUERY_TRY_MARRIAGE_CONCEPTION_UPDATE: &str = r#"
|
||||
AND ma.mother_age_days < 18993
|
||||
AND random() < ma.prob_year
|
||||
)
|
||||
UPDATE falukant_data.relationship r
|
||||
SET marriage_pregnancy_due_at = NOW() + INTERVAL '5 days'
|
||||
UPDATE falukant_data.relationship r
|
||||
SET marriage_pregnancy_due_at = NOW() + INTERVAL '18 hours'
|
||||
FROM conceivable c
|
||||
WHERE r.id = c.relationship_id;
|
||||
"#;
|
||||
@@ -3962,14 +3962,25 @@ pub const QUERY_GET_LOVER_PREGNANCY_CANDIDATES: &str = r#"
|
||||
)
|
||||
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 (c1.gender = 'female' AND c2.gender = 'male')
|
||||
OR (c1.gender = 'male' AND c2.gender = 'female')
|
||||
WHERE ((c1.gender = 'female' AND c2.gender = 'male')
|
||||
OR (c1.gender = 'male' AND c2.gender = 'female'))
|
||||
AND rs.affection >= 45
|
||||
AND rs.maintenance_level >= 30
|
||||
-- `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 >= NOW() - INTERVAL '50 days'
|
||||
AND c_female.pregnancy_due_at IS NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM falukant_data.relationship rm
|
||||
JOIN falukant_type.relationship rtm
|
||||
ON rtm.id = rm.relationship_type_id AND rtm.tr = 'married'
|
||||
JOIN falukant_data.character cm1 ON cm1.id = rm.character1_id
|
||||
JOIN falukant_data.character cm2 ON cm2.id = rm.character2_id
|
||||
WHERE rm.marriage_pregnancy_due_at IS NOT NULL
|
||||
AND ((cm1.gender = 'female' AND cm1.id = c_female.id)
|
||||
OR (cm2.gender = 'female' AND cm2.id = c_female.id))
|
||||
)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM falukant_data.child_relation cr
|
||||
@@ -3997,48 +4008,28 @@ pub const QUERY_GET_LOVER_PREGNANCY_CANDIDATES: &str = r#"
|
||||
);
|
||||
"#;
|
||||
|
||||
pub const QUERY_LOVER_BIRTH_PENALTY_MARRIAGE: &str = r#"
|
||||
UPDATE falukant_data.relationship_state rs
|
||||
SET marriage_satisfaction = GREATEST(0, COALESCE(rs.marriage_satisfaction, 55) - 8),
|
||||
updated_at = NOW()
|
||||
FROM falukant_data.relationship r
|
||||
JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id
|
||||
WHERE rt.id = r.relationship_type_id
|
||||
AND rs.relationship_id = r.id
|
||||
AND rt.tr IN ('married', 'engaged', 'wooing')
|
||||
AND (r.character1_id = $1::int OR r.character2_id = $1::int);
|
||||
"#;
|
||||
|
||||
pub const QUERY_LOVER_BIRTH_PENALTY_REPUTATION: &str = r#"
|
||||
UPDATE falukant_data.character
|
||||
SET reputation = GREATEST(0::numeric, COALESCE(reputation, 50::numeric) - 4::numeric),
|
||||
updated_at = NOW()
|
||||
WHERE id = $1::int;
|
||||
"#;
|
||||
|
||||
pub const QUERY_INSERT_CHILD_RELATION_LOVER: &str = r#"
|
||||
INSERT INTO falukant_data.child_relation (
|
||||
father_character_id,
|
||||
mother_character_id,
|
||||
child_character_id,
|
||||
name_set,
|
||||
legitimacy,
|
||||
birth_context,
|
||||
public_known,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
$1::int,
|
||||
$2::int,
|
||||
$3::int,
|
||||
FALSE,
|
||||
'hidden_bastard',
|
||||
'lover',
|
||||
FALSE,
|
||||
NOW(),
|
||||
NOW()
|
||||
);
|
||||
/// Liebschafts-Konzeption setzt eine geplante Schwangerschaft am Mutter-Charakter
|
||||
/// (gleicher Geburtsweg wie Admin/Spiel): Geburt erfolgt, wenn `pregnancy_due_at <= NOW()`.
|
||||
pub const QUERY_SET_CHARACTER_PREGNANCY_FROM_LOVER: &str = r#"
|
||||
UPDATE falukant_data.character c_m
|
||||
SET pregnancy_due_at = NOW() + INTERVAL '18 hours',
|
||||
pregnancy_father_character_id = $2::int,
|
||||
updated_at = NOW()
|
||||
WHERE c_m.id = $1::int
|
||||
AND c_m.health > 0
|
||||
AND c_m.pregnancy_due_at IS NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM falukant_data.relationship rm
|
||||
JOIN falukant_type.relationship rtm
|
||||
ON rtm.id = rm.relationship_type_id AND rtm.tr = 'married'
|
||||
JOIN falukant_data.character cm1 ON cm1.id = rm.character1_id
|
||||
JOIN falukant_data.character cm2 ON cm2.id = rm.character2_id
|
||||
WHERE rm.marriage_pregnancy_due_at IS NOT NULL
|
||||
AND ((cm1.gender = 'female' AND cm1.id = c_m.id)
|
||||
OR (cm2.gender = 'female' AND cm2.id = c_m.id))
|
||||
)
|
||||
RETURNING c_m.id AS mother_cid;
|
||||
"#;
|
||||
|
||||
/// Pro Mutter maximal eine Geburt pro Kalendertag (jeder Vater); Rust prüft zusätzlich vor Insert.
|
||||
|
||||
@@ -193,7 +193,7 @@ impl UserCharacterWorker {
|
||||
}
|
||||
|
||||
/// Ehe: Geburten/stale stündlich; Konzeption höchstens einmal pro Kalendertag (ein Jahreswurf, `prob_year`).
|
||||
/// Konzeption setzt `marriage_pregnancy_due_at` (+5 Tage); Geburt über `QUERY_GET_MARRIAGE_BIRTH_DELIVERIES`.
|
||||
/// Konzeption setzt `marriage_pregnancy_due_at` (+18 Stunden); Geburt über `QUERY_GET_MARRIAGE_BIRTH_DELIVERIES`.
|
||||
/// Kein separates „Hochzeitsnacht“-Event — erste Konzeption am nächsten Tageslauf nach der Hochzeit.
|
||||
fn maybe_run_hourly_pregnancies(&mut self) {
|
||||
let now = Instant::now();
|
||||
@@ -677,7 +677,7 @@ 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)? {
|
||||
if mother_already_had_birth_today(conn, mother_cid)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -738,7 +738,7 @@ 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)? {
|
||||
if mother_already_had_birth_today(conn, mother_cid)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user