1 ///////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2011 by The Allacrost Project
3 //            Copyright (C) 2012-2016 by Bertram (Valyria Tear)
4 //                         All Rights Reserved
5 //
6 // This code is licensed under the GNU GPL version 2. It is free software
7 // and you may modify it and/or redistribute it under the terms of this license.
8 // See https://www.gnu.org/copyleft/gpl.html for details.
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef __MAP_DIALOGUE_HEADER__
12 #define __MAP_DIALOGUE_HEADER__
13 
14 #include "common/dialogue.h"
15 
16 namespace vt_map
17 {
18 
19 namespace private_map
20 {
21 
22 class MapSprite;
23 
24 /** ****************************************************************************
25 *** \brief Represents a dialogue that occurs between one or more sprites on a map
26 *** ***************************************************************************/
27 class SpriteDialogue : public vt_common::Dialogue
28 {
29 public:
30     //! \brief Constructor with auto-generated dialogue ID
31     SpriteDialogue();
32 
33     //! \brief Dialogue with auto-generated id and event name
34     //! \param dialogue_event_name event name used and stored in the 'dialogues' save data table.
35     //! The event name is used to know whether the player has already seen a dialogue
36     //! and display the dialogue bubble accordingly.
37     //! If empty, the event is not stored.
38     explicit SpriteDialogue(const std::string& dialogue_event_name);
39 
~SpriteDialogue()40     virtual ~SpriteDialogue() override
41     {
42     }
43 
44     //! \brief A C++ wrapper made to create a new object from scripting,
45     //! without letting Lua handling the object life-cycle.
46     //! \note We don't permit luabind to use constructors here as it can't currently
47     //! give the object ownership at construction time.
48     static SpriteDialogue* Create();
49     static SpriteDialogue* Create(const std::string& dialogue_event_name);
50 
51     //! \brief Indicates if this dialogue has already been seen by the player.
HasAlreadySeen()52     bool HasAlreadySeen() const {
53         return _dialogue_seen;
54     }
55 
56     //! \brief Set the dialogue as seen by the player, and stores its states
57     //! in the save data if its event name isn't empty.
58     void SetAsSeen(bool seen = true);
59 
60     /** \brief Adds a new line of text to the dialogue
61     *** \param text The text to show on the screen
62     *** \param speaker The VirtualSprite speaking this line
63     ***
64     *** The following line properties are set when using this call:
65     *** - proceed to next sequential line, no display time, no event
66     **/
67     void AddLine(const std::string &text, MapSprite *speaker);
68 
69     void AddLineEmote(const std::string &text, MapSprite *speaker,
70                       const std::string &emote_id);
71 
72     /** \brief Adds a new line of text to the dialogue
73     *** \param text The text to show on the screen
74     *** \param speaker The VirtualSprite speaking this line
75     *** \param next_line The line of dialogue which should follow this one
76     ***
77     *** The following line properties are set when using this call:
78     *** - no display time, no event
79     **/
80     void AddLine(const std::string &text, MapSprite *speaker, int32_t next_line);
81 
82     /** \brief Adds a new line of text to the dialogue that uses a display time
83     *** \param text The text to show on the screen
84     *** \param speaker VirtualSprite speaking this line
85     *** \param display_time The number of milliseconds that the line should be displayed for
86     ***
87     *** The following line properties are set when using this call:
88     *** - proceed to next sequential line, no event
89     **/
90     void AddLineTimed(const std::string &text, MapSprite *speaker, uint32_t display_time);
91 
92     /** \brief Adds a new line of text to the dialogue that uses a display time
93     *** \param text The text to show on the screen
94     *** \param speaker The VirtualSprite speaking this line
95     *** \param next_line The line of dialogue which should follow this one
96     *** \param display_time The number of milliseconds that the line should be displayed for
97     ***
98     *** The following line properties are set when using this call:
99     *** - no event
100     **/
101     void AddLineTimed(const std::string &text, MapSprite *speaker, int32_t next_line, uint32_t display_time);
102 
103     /** \brief Adds a new line of text to the dialogue that uses a map event
104     *** \param text The text to show on the screen
105     *** \param speaker The VirtualSprite speaking this line
106     *** \param end_event_id The ID of the event to execute after this line finishes
107     *** \param begin_event_id The ID of the event to execute when the line starts
108     ***
109     *** The following line properties are set when using this call:
110     *** - proceed to next sequential line, no display time
111     **/
112     void AddLineEvent(const std::string &text, MapSprite *speaker,
113                       const std::string &begin_event_id, const std::string &end_event_id);
114 
115     void AddLineEventEmote(const std::string &text, MapSprite *speaker,
116                            const std::string &begin_event_id, const std::string &end_event_id,
117                            const std::string &emote_id);
118 
119     /** \brief Adds a new line of text to the dialogue that uses a map event
120     *** \param text The text to show on the screen
121     *** \param speaker The VirtualSprite speaking this line
122     *** \param next_line The line of dialogue which should follow this one
123     *** \param display_time The number of milliseconds that the line should be displayed for
124     ***
125     *** The following line properties are set when using this call:
126     *** - no event
127     **/
128     void AddLineEvent(const std::string &text, MapSprite *speaker, int32_t next_line,
129                       const std::string &begin_event_id, const std::string &end_event_id);
130 
131     /** \brief Adds a new line of text to the dialogue that uses a map event
132     *** \param text The text to show on the screen
133     *** \param speaker The VirtualSprite speaking this line
134     *** \param display_time The number of milliseconds that the line should be displayed for
135     *** \param end_event_id The ID of the event to execute after this line finishes
136     *** \param begin_event_id The ID of the event to execute when the line starts
137     ***
138     *** The following line properties are set when using this call:
139     *** - proceed to next sequential line
140     **/
141     void AddLineTimedEvent(const std::string &text, MapSprite *speaker, uint32_t display_time,
142                            const std::string &begin_event_id, const std::string &end_event_id);
143 
144     /** \brief Adds a new line of text to the dialogue that uses a map event
145     *** \param text The text to show on the screen
146     *** \param speaker The VirtualSprite speaking this line
147     *** \param next_line The line of dialogue which should follow this one
148     *** \param display_time The number of milliseconds that the line should be displayed for
149     *** \param begin_event_id The ID of the event to execute when the line starts
150     *** \param end_event_id The ID of the event to execute after this line finishes
151     *** \param emote_id The ID of the emote to trigger on the speaker map sprite.
152     **/
153     void AddLineTimedEvent(const std::string &text, MapSprite *speaker, int32_t next_line, uint32_t display_time,
154                            const std::string &begin_event_id, const std::string &end_event_id, const std::string& emote_id);
155 
156     /** \brief Adds an option to the most recently added line of text
157     *** \param text The text for this particular option
158     *** \note If no lines have been added to the dialogue yet, this option will not be added and a warning will be issued
159     ***
160     *** The following option properties are set when using this call:
161     *** - proceed to next sequential line, no event
162     **/
163     void AddOption(const std::string &text);
164 
165     /** \brief Adds an option to the most recently added line of text
166     *** \param text The text for this particular option
167     *** \param next_line The index value of the next line of dialogue to display should this option be selected
168     *** \note If no lines have been added to the dialogue yet, this option will not be added and a warning will be issued
169     ***
170     *** The following option properties are set when using this call:
171     *** - no event
172     **/
173     void AddOption(const std::string &text, int32_t next_line);
174 
175     /** \brief Adds an option to the most recently added line of text
176     *** \param text The text for this particular option
177     *** \param event_id The ID of the event to execute should this option be selected
178     *** \note If no lines have been added to the dialogue yet, this option will not be added and a warning will be issued
179     ***
180     *** The following option properties are set when using this call:
181     *** - proceed to next sequential line
182     **/
183     void AddOptionEvent(const std::string &text, const std::string &event_id);
184 
185     /** \brief Adds an option to the most recently added line of text
186     *** \param text The text for this particular option
187     *** \param next_line The index value of the next line of dialogue to display should this option be selected
188     *** \param event_id The ID of the event to execute should this option be selected
189     *** \note If no lines have been added to the dialogue yet, this option will not be added and a warning will be issued
190     **/
191     void AddOptionEvent(const std::string &text, int32_t next_line, const std::string &event_id);
192 
193     /** \brief Checks all the data stored by the dialogue class to ensure that it is acceptable and ready for use
194     *** \return True if the validation was successful, false if any problems were discovered
195     ***
196     *** \note This function should not be called until after all map sprites have been added. The function checks that each
197     *** speaker is valid and stored in the map's object list, so if you perform this check before you've added all the speakers
198     *** to the object list of MapMode, the validation will fail.
199     **/
200     bool Validate();
201 
202     //! \name Methods for retrieving properties of a specific line
203     //@{
204     //! \brief Returns the object of the speaker for the line specified (or nullptr if the line index was invalid)
GetLineSpeaker(uint32_t line)205     MapSprite* GetLineSpeaker(uint32_t line) const {
206         if(line >= _line_count) return nullptr;
207         else return _speakers[line];
208     }
209 
210     //! \brief Returns the ID of the event to execute for the line specified (or zero if the line index was invalid)
GetLineEndEvent(uint32_t line)211     std::string GetLineEndEvent(uint32_t line) const {
212         if(line >= _line_count) return std::string();
213         else return _end_events[line];
214     }
215 
216     //! \brief Returns the ID of the event to execute for the line specified (or zero if the line index was invalid)
GetLineBeginEvent(uint32_t line)217     std::string GetLineBeginEvent(uint32_t line) const {
218         if(line >= _line_count) return std::string();
219         else return _begin_events[line];
220     }
221 
GetLineEmote(uint32_t line)222     std::string GetLineEmote(uint32_t line) const {
223         if(line >= _line_count) return std::string();
224         else return _emote_events[line];
225     }
226     //@}
227 
228     //! \name Class Member Access Functions
229     //@{
GetEventName()230     const std::string &GetEventName() const {
231         return _event_name;
232     }
233 
IsInputBlocked()234     bool IsInputBlocked() const {
235         return _input_blocked;
236     }
237 
IsRestoreState()238     bool IsRestoreState() const {
239         return _restore_state;
240     }
241 
SetInputBlocked(bool blocked)242     void SetInputBlocked(bool blocked) {
243         _input_blocked = blocked;
244     }
245 
SetRestoreState(bool restore)246     void SetRestoreState(bool restore) {
247         _restore_state = restore;
248     }
249 
SetEventAtDialogueEnd(const std::string & event_id)250     void SetEventAtDialogueEnd(const std::string& event_id) {
251         _event_after_dialogue_end = event_id;
252     }
253 
GetEventAtDialogueEnd()254     const std::string& GetEventAtDialogueEnd() const {
255         return _event_after_dialogue_end;
256     }
257     //@}
258 
259 private:
260     //! \brief If true, dialogue will ignore user input and instead execute independently
261     bool _input_blocked;
262 
263     //! \brief If true, the state of map sprites participating in this dialogue will be reset after the dialogue completes
264     bool _restore_state;
265 
266     //! \brief The event name for this dialogue that is stored in the saved game file, if not empty.
267     //! This permit the engine to know whether the player already saw a dialogue event when leaving the map
268     //! and coming back.
269     std::string _event_name;
270 
271     //! \brief Tells whether the dialogue has been seen by the player.
272     bool _dialogue_seen;
273 
274     //! \brief Contains MapSprite speakers of each line
275     std::vector<MapSprite*> _speakers;
276 
277     //! \brief An optional MapEvent that may occur when a line begins
278     std::vector<std::string> _begin_events;
279 
280     //! \brief An optional MapEvent that may occur after each line is completed
281     std::vector<std::string> _end_events;
282 
283     //! \brief the emote to play on the speaker sprite before starting the line (and if possible).
284     std::vector<std::string> _emote_events;
285 
286     //! \brief The optional event id to trigger after dialogue's end.
287     //! This is handly to trigger other scene events after a dialogue.
288     std::string _event_after_dialogue_end;
289 };
290 
291 } // namespace private_map
292 
293 } // namespace vt_map
294 
295 #endif // __MAP_DIALOGUE_HEADER__
296