Add FalukantFamilyWorker and related SQL queries: Introduced the FalukantFamilyWorker to manage family-related logic, including marriage satisfaction and relationship states. Added new SQL queries for handling lover relationships and marriage updates, enhancing the overall functionality of family dynamics in the application.

This commit is contained in:
Torsten Schulz (local)
2026-03-20 10:26:15 +01:00
parent f9c80bbd6b
commit 6a5ff4557e
8 changed files with 1164 additions and 1 deletions

View File

@@ -1677,7 +1677,10 @@ pub const QUERY_SET_MARRIAGES_BY_PARTY: &str = r#"
SELECT id
FROM falukant_type.relationship AS rt
WHERE rt.tr = 'married'
)
),
marriage_satisfaction = 55,
marriage_drift_high = 0,
marriage_drift_low = 0
WHERE rel.id IN (
SELECT rel2.id
FROM falukant_data.party AS p
@@ -2005,3 +2008,266 @@ pub const QUERY_GET_CHARACTERS_FOR_CHURCH_OFFICE: &str = r#"
LIMIT $2;
"#;
// --- Falukant: Familie / Liebhaber / Ehezufriedenheit (siehe migrations/001_falukant_family_lovers.sql) ---
pub const QUERY_FAMILY_SCHEMA_READY: &str = r#"
SELECT EXISTS (
SELECT 1
FROM information_schema.columns
WHERE table_schema = 'falukant_data'
AND table_name = 'relationship_state'
AND column_name = 'last_daily_processed_at'
) AS ready;
"#;
pub const QUERY_GET_ACTIVE_LOVER_ROWS_FOR_DAILY: &str = r#"
SELECT
r.id AS rel_id,
r.character1_id AS c1,
r.character2_id AS c2,
rs.lover_role,
rs.affection,
rs.visibility,
rs.discretion,
rs.maintenance_level,
rs.status_fit,
rs.monthly_base_cost,
rs.scandal_extra_daily_pct,
rs.months_underfunded,
c1.gender AS g1,
c2.gender AS g2,
COALESCE(t1.tr, '') AS title1_tr,
COALESCE(t2.tr, '') AS title2_tr,
COALESCE(c1.reputation, 50)::float8 AS rep1,
COALESCE(c2.reputation, 50)::float8 AS rep2,
fu1.id AS user1_id,
fu2.id AS user2_id
FROM falukant_data.relationship r
JOIN falukant_type.relationship rt
ON rt.id = r.relationship_type_id AND rt.tr = 'lover'
JOIN falukant_data.relationship_state rs ON rs.relationship_id = r.id
JOIN falukant_data.character c1 ON c1.id = r.character1_id
JOIN falukant_data.character c2 ON c2.id = r.character2_id
LEFT JOIN falukant_type.title t1 ON t1.id = c1.title_of_nobility
LEFT JOIN falukant_type.title t2 ON t2.id = c2.title_of_nobility
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 rs.active = true
AND (
rs.last_daily_processed_at IS NULL
OR (rs.last_daily_processed_at::date < CURRENT_DATE)
);
"#;
pub const QUERY_GET_ACTIVE_LOVER_ROWS_FOR_MONTHLY: &str = r#"
SELECT
r.id AS rel_id,
r.character1_id AS c1,
r.character2_id AS c2,
rs.lover_role,
rs.affection,
rs.visibility,
rs.discretion,
rs.maintenance_level,
rs.status_fit,
rs.monthly_base_cost,
rs.scandal_extra_daily_pct,
rs.months_underfunded,
c1.gender AS g1,
c2.gender AS g2,
COALESCE(t1.tr, '') AS title1_tr,
COALESCE(t2.tr, '') AS title2_tr,
COALESCE(c1.reputation, 50)::float8 AS rep1,
COALESCE(c2.reputation, 50)::float8 AS rep2,
fu1.id AS user1_id,
fu2.id AS user2_id
FROM falukant_data.relationship r
JOIN falukant_type.relationship rt
ON rt.id = r.relationship_type_id AND rt.tr = 'lover'
JOIN falukant_data.relationship_state rs ON rs.relationship_id = r.id
JOIN falukant_data.character c1 ON c1.id = r.character1_id
JOIN falukant_data.character c2 ON c2.id = r.character2_id
LEFT JOIN falukant_type.title t1 ON t1.id = c1.title_of_nobility
LEFT JOIN falukant_type.title t2 ON t2.id = c2.title_of_nobility
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 rs.active = true
AND (
rs.last_monthly_processed_at IS NULL
OR date_trunc('month', rs.last_monthly_processed_at) < date_trunc('month', CURRENT_TIMESTAMP)
);
"#;
pub const QUERY_UPDATE_LOVER_VISIBILITY_DISCRETION: &str = r#"
UPDATE falukant_data.relationship_state
SET visibility = $1::smallint,
discretion = $2::smallint
WHERE relationship_id = $3::int;
"#;
pub const QUERY_UPDATE_LOVER_UNDERPAY_STATE: &str = r#"
UPDATE falukant_data.relationship_state
SET affection = $1::smallint,
discretion = $2::smallint,
visibility = $3::smallint,
months_underfunded = $4::smallint,
scandal_extra_daily_pct = $5::smallint
WHERE relationship_id = $6::int;
"#;
pub const QUERY_GET_MARRIAGE_ROWS: &str = r#"
SELECT
r.id AS marriage_id,
r.character1_id AS m1,
r.character2_id AS m2,
r.marriage_satisfaction,
r.marriage_drift_high,
r.marriage_drift_low,
COALESCE(t1.tr, '') AS title1_tr,
COALESCE(t2.tr, '') AS title2_tr
FROM falukant_data.relationship r
JOIN falukant_type.relationship rt ON rt.id = r.relationship_type_id
AND rt.tr IN ('married', 'engaged', 'wooing')
JOIN falukant_data.character c1 ON c1.id = r.character1_id
JOIN falukant_data.character c2 ON c2.id = r.character2_id
LEFT JOIN falukant_type.title t1 ON t1.id = c1.title_of_nobility
LEFT JOIN falukant_type.title t2 ON t2.id = c2.title_of_nobility;
"#;
pub const QUERY_UPDATE_MARRIAGE_STATE: &str = r#"
UPDATE falukant_data.relationship
SET marriage_satisfaction = $1::smallint,
marriage_drift_high = $2::smallint,
marriage_drift_low = $3::smallint
WHERE id = $4::int;
"#;
pub const QUERY_MARRIAGE_SUBTRACT_SATISFACTION: &str = r#"
UPDATE falukant_data.relationship r
SET marriage_satisfaction = GREATEST(0, r.marriage_satisfaction - $2::int)
FROM falukant_type.relationship rt
WHERE rt.id = r.relationship_type_id
AND rt.tr IN ('married', 'engaged', 'wooing')
AND r.id = $1::int;
"#;
pub const QUERY_RESET_LOVER_UNDERPAY_COUNTERS: &str = r#"
UPDATE falukant_data.relationship_state
SET months_underfunded = 0
WHERE relationship_id = $1::int;
"#;
pub const QUERY_MARK_LOVER_DAILY_DONE: &str = r#"
UPDATE falukant_data.relationship_state
SET last_daily_processed_at = NOW()
WHERE relationship_id = $1::int;
"#;
pub const QUERY_MARK_LOVER_MONTHLY_DONE: &str = r#"
UPDATE falukant_data.relationship_state
SET last_monthly_processed_at = NOW()
WHERE relationship_id = $1::int;
"#;
pub const QUERY_UPDATE_CHARACTER_REPUTATION: &str = r#"
UPDATE falukant_data.character
SET reputation = $1::numeric,
updated_at = NOW()
WHERE id = $2::int;
"#;
pub const QUERY_GET_LOVER_PREGNANCY_CANDIDATES: &str = r#"
SELECT
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 rt ON rt.id = r.relationship_type_id AND rt.tr = 'lover'
JOIN falukant_data.relationship_state rs ON rs.relationship_id = r.id AND rs.active = true
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 (c1.gender = 'female' AND c2.gender = 'male')
OR (c1.gender = 'male' AND c2.gender = 'female')
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 NOT EXISTS (
SELECT 1
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)
AND cr.created_at >= date_trunc('month', CURRENT_TIMESTAMP)
)
AND (CURRENT_DATE - c_female.birthdate::date) >= 4380
AND (CURRENT_DATE - c_female.birthdate::date) < 18993
AND random() * 100.0 < (
LEAST(12.0, GREATEST(0.0,
CASE rs.lover_role
WHEN 'secret_affair' THEN 2.0
WHEN 'lover' THEN 4.0
WHEN 'mistress_or_favorite' THEN 6.0
ELSE 0.0
END
+ CASE WHEN rs.affection >= 75 THEN 2.0 ELSE 0.0 END
+ CASE WHEN rs.visibility >= 70 AND rs.affection < 50 THEN -2.0 ELSE 0.0 END
+ CASE
WHEN (CURRENT_DATE - c_female.birthdate::date) > 14600
THEN -3.0
ELSE 0.0
END
))
);
"#;
pub const QUERY_LOVER_BIRTH_PENALTY_MARRIAGE: &str = r#"
UPDATE falukant_data.relationship r
SET marriage_satisfaction = GREATEST(0, r.marriage_satisfaction - 8)
FROM falukant_type.relationship rt
WHERE rt.id = r.relationship_type_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()
);
"#;