veloren_common/comp/
dialogue.rs

1use serde::{Deserialize, Serialize};
2use vek::{Vec2, Vec3};
3
4use super::Item;
5
6#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
7pub struct AskedLocation {
8    pub name: String,
9    pub origin: Vec2<i32>,
10}
11
12#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
13pub enum PersonType {
14    Merchant,
15    Villager { name: String },
16}
17
18#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
19pub struct AskedPerson {
20    pub person_type: PersonType,
21    pub origin: Option<Vec3<i32>>,
22}
23
24impl AskedPerson {
25    pub fn name(&self) -> String {
26        match &self.person_type {
27            PersonType::Merchant => "The Merchant".to_string(),
28            PersonType::Villager { name } => name.clone(),
29        }
30    }
31}
32
33/// Conversation subject
34#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
35pub enum Subject {
36    /// Using simple interaction with NPC
37    /// This is meant to be the default behavior of talking
38    /// NPC will throw a random dialogue to you
39    Regular,
40    /// Asking for trading
41    /// Ask the person to trade with you
42    /// NPC will either invite you to trade, or decline
43    Trade,
44    /// Inquiring the mood of the NPC
45    /// NPC will explain what his mood is, and why.
46    /// Can lead to potential quests if the NPC has a bad mood
47    /// Else it'll just be flavor text explaining why he got this mood
48    Mood,
49    /// Asking for a location
50    /// NPC will either know where this location is, or not
51    /// It'll tell you which direction and approx what distance it is from you
52    Location(AskedLocation),
53    /// Asking for a person's location
54    /// NPC will either know where this person is, or not
55    /// It'll tell you which direction and approx what distance it is from you
56    Person(AskedPerson),
57    /// Asking for work
58    /// NPC will give you a quest if his mood is bad enough
59    /// So either it'll tell you something to do, or just say that he got
60    /// nothing
61    Work,
62}
63
64/// Context of why a NPC has a specific mood (good, neutral, bad, ...)
65#[derive(Clone, Debug)]
66pub enum MoodContext {
67    /// The weather is good, sunny, appeasing, etc...
68    GoodWeather,
69    /// Someone completed a quest and enlightened this NPC's day
70    QuestSucceeded { hero: String, quest_desc: String },
71
72    /// Normal day, same as yesterday, nothing relevant to say about it, that's
73    /// everyday life
74    EverydayLife,
75    /// Need one or more items in order to complete a personal task, or for
76    /// working
77    NeedItem { item: Item, quantity: u16 },
78
79    /// A personal good has been robbed! Gotta find a replacement
80    MissingItem { item: Item },
81}
82
83// Note: You can add in-between states if needed
84/// NPC mood status indicator
85#[derive(Clone, Debug)]
86pub enum MoodState {
87    /// The NPC is happy!
88    Good(MoodContext),
89    /// The NPC is having a normal day
90    Neutral(MoodContext),
91    /// The NPC got a pretty bad day. He may even need player's help!
92    Bad(MoodContext),
93}
94
95// TODO: this should return common_i18n::Content
96impl MoodState {
97    pub fn describe(&self) -> String {
98        match self {
99            MoodState::Good(context) => format!("I'm so happy, {}", context.describe()),
100            MoodState::Neutral(context) => context.describe(),
101            MoodState::Bad(context) => {
102                format!("I'm mad, {}", context.describe())
103            },
104        }
105    }
106}
107
108// TODO: this should return common_i18n::Content
109impl MoodContext {
110    pub fn describe(&self) -> String {
111        match &self {
112            MoodContext::GoodWeather => "The weather is great today!".to_string(),
113            MoodContext::QuestSucceeded { hero, quest_desc } => {
114                format!("{} helped me on {}", hero, quest_desc)
115            },
116            &MoodContext::EverydayLife => "Life's going as always.".to_string(),
117            MoodContext::NeedItem {
118                item: _,
119                quantity: _,
120            } => {
121                // format!("I need {} {}!", quantity, item.name())
122                "I need some item, not just any item!".to_string()
123            },
124            &MoodContext::MissingItem { item: _ } => {
125                // format!("Someone robbed my {}!", item.name())
126                "Someone robbed me of my item!".to_string()
127            },
128        }
129    }
130}