proof_engine/narrative/
dialogue.rs1use super::motivation::{Motivation, Personality, Need};
4use crate::worldgen::Rng;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum Tone { Friendly, Hostile, Neutral, Fearful, Respectful, Sarcastic, Desperate, Wise }
8
9#[derive(Debug, Clone)]
10pub struct DialogueLine { pub speaker: String, pub text: String, pub tone: Tone }
11
12pub fn generate_greeting(name: &str, personality: &Personality, relationship: f32, rng: &mut Rng) -> DialogueLine {
14 let tone = if relationship > 0.5 { Tone::Friendly }
15 else if relationship < -0.3 { Tone::Hostile }
16 else { Tone::Neutral };
17
18 let templates = match tone {
19 Tone::Friendly => vec![
20 format!("Welcome, friend! What brings you to my door?"),
21 format!("Ah, good to see you again! Come, sit."),
22 format!("A familiar face! The day grows brighter."),
23 ],
24 Tone::Hostile => vec![
25 format!("What do you want? Make it quick."),
26 format!("You again. I thought I made myself clear."),
27 format!("Speak, before I change my mind about listening."),
28 ],
29 _ => vec![
30 format!("Greetings, traveler."),
31 format!("What can I do for you?"),
32 format!("Hmm? Oh. You need something?"),
33 ],
34 };
35
36 DialogueLine {
37 speaker: name.to_string(),
38 text: templates[rng.next_u64() as usize % templates.len()].clone(),
39 tone,
40 }
41}
42
43pub fn generate_topic_response(name: &str, topic: &str, belief_value: f32, rng: &mut Rng) -> DialogueLine {
45 let tone = if belief_value > 0.5 { Tone::Respectful }
46 else if belief_value < -0.3 { Tone::Sarcastic }
47 else { Tone::Neutral };
48
49 let text = if belief_value > 0.5 {
50 format!("{} is something I hold dear. Let me tell you more...", topic)
51 } else if belief_value < -0.3 {
52 format!("{}? Hah. Don't get me started on that nonsense.", topic)
53 } else {
54 format!("{}? I suppose I have some thoughts on the matter.", topic)
55 };
56
57 DialogueLine { speaker: name.to_string(), text, tone }
58}
59
60pub fn unreliable_narrate(event: &str, bias: f32, perspective: &str, rng: &mut Rng) -> String {
62 if bias > 0.5 {
63 format!("As {} recalls it, {} — though they may be too generous in their retelling.", perspective, event)
64 } else if bias < -0.3 {
65 format!("According to {}, {} — but one wonders if spite colors the memory.", perspective, event)
66 } else {
67 format!("{} remembers: {}", perspective, event)
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test_greeting_friendly() {
77 let personality = Personality { openness: 0.8, conscientiousness: 0.5, extraversion: 0.7, agreeableness: 0.8, neuroticism: 0.2 };
78 let mut rng = Rng::new(42);
79 let line = generate_greeting("Elder", &personality, 0.8, &mut rng);
80 assert_eq!(line.tone, Tone::Friendly);
81 }
82
83 #[test]
84 fn test_unreliable_narrator() {
85 let mut rng = Rng::new(42);
86 let biased = unreliable_narrate("the battle was fierce", 0.8, "the general", &mut rng);
87 assert!(biased.contains("generous"));
88 }
89}