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 #include "modes/map/map_dialogues/map_sprite_dialogue.h"
12
13 #include "modes/map/map_dialogue_supervisor.h"
14 #include "modes/map/map_event_supervisor.h"
15 #include "modes/map/map_dialogues/map_dialogue_options.h"
16 #include "modes/map/map_sprites/map_sprite.h"
17 #include "modes/map/map_mode.h"
18
19 #include "common/global/global.h"
20
21 namespace vt_map
22 {
23
24 namespace private_map
25 {
26
SpriteDialogue()27 SpriteDialogue::SpriteDialogue() :
28 Dialogue(MapMode::CurrentInstance()->GetDialogueSupervisor()->GenerateDialogueID()),
29 _input_blocked(false),
30 _restore_state(true),
31 _dialogue_seen(false)
32 {
33 // Auto-registers the dialogue for later deletion handling.
34 MapMode::CurrentInstance()->GetDialogueSupervisor()->AddDialogue(this);
35 }
36
SpriteDialogue(const std::string & dialogue_event_name)37 SpriteDialogue::SpriteDialogue(const std::string& dialogue_event_name) :
38 Dialogue(MapMode::CurrentInstance()->GetDialogueSupervisor()->GenerateDialogueID()),
39 _input_blocked(false),
40 _restore_state(true),
41 _event_name(dialogue_event_name)
42 {
43 // Check whether the dialogue as already been seen
44 _dialogue_seen = false;
45 if (_event_name.empty())
46 return;
47
48 int32_t seen = vt_global::GlobalManager->GetGameEvents().GetEventValue("dialogues", _event_name);
49 if (seen > 0)
50 _dialogue_seen = true;
51
52 // Auto-registers the dialogue for later deletion handling.
53 MapMode::CurrentInstance()->GetDialogueSupervisor()->AddDialogue(this);
54 }
55
Create()56 SpriteDialogue* SpriteDialogue::Create()
57 {
58 // The object auto register to the object supervisor
59 // and will later handle deletion.
60 return new SpriteDialogue();
61 }
62
Create(const std::string & dialogue_event_name)63 SpriteDialogue* SpriteDialogue::Create(const std::string& dialogue_event_name)
64 {
65 // The object auto register to the object supervisor
66 // and will later handle deletion.
67 return new SpriteDialogue(dialogue_event_name);
68 }
69
SetAsSeen(bool seen)70 void SpriteDialogue::SetAsSeen(bool seen)
71 {
72 _dialogue_seen = seen;
73
74 if (_event_name.empty())
75 return;
76
77 // Stores the dialogue state in the save data
78 int32_t event_value = 0;
79 if (_dialogue_seen)
80 event_value = 1;
81
82 vt_global::GlobalManager->GetGameEvents().SetEventValue("dialogues", _event_name, event_value);
83 }
84
AddLine(const std::string & text,MapSprite * speaker)85 void SpriteDialogue::AddLine(const std::string &text, MapSprite *speaker)
86 {
87 AddLineTimedEvent(text, speaker,
88 vt_common::DIALOGUE_NEXT_LINE, vt_common::DIALOGUE_NO_TIMER,
89 std::string(), std::string(), std::string());
90 }
91
AddLineEmote(const std::string & text,MapSprite * speaker,const std::string & emote_id)92 void SpriteDialogue::AddLineEmote(const std::string &text, MapSprite *speaker,
93 const std::string &emote_id)
94 {
95 AddLineTimedEvent(text, speaker,
96 vt_common::DIALOGUE_NEXT_LINE, vt_common::DIALOGUE_NO_TIMER,
97 std::string(), std::string(), emote_id);
98 }
99
AddLine(const std::string & text,MapSprite * speaker,int32_t next_line)100 void SpriteDialogue::AddLine(const std::string &text, MapSprite *speaker, int32_t next_line)
101 {
102 AddLineTimedEvent(text, speaker,
103 next_line, vt_common::DIALOGUE_NO_TIMER,
104 std::string(), std::string(), std::string());
105 }
106
AddLineTimed(const std::string & text,MapSprite * speaker,uint32_t display_time)107 void SpriteDialogue::AddLineTimed(const std::string &text, MapSprite *speaker, uint32_t display_time)
108 {
109 AddLineTimedEvent(text, speaker,
110 vt_common::DIALOGUE_NEXT_LINE, display_time,
111 std::string(), std::string(), std::string());
112 }
113
AddLineTimed(const std::string & text,MapSprite * speaker,int32_t next_line,uint32_t display_time)114 void SpriteDialogue::AddLineTimed(const std::string &text, MapSprite *speaker, int32_t next_line, uint32_t display_time)
115 {
116 AddLineTimedEvent(text, speaker,
117 next_line, display_time,
118 std::string(), std::string(), std::string());
119 }
120
AddLineEvent(const std::string & text,MapSprite * speaker,const std::string & begin_event_id,const std::string & end_event_id)121 void SpriteDialogue::AddLineEvent(const std::string &text, MapSprite *speaker,
122 const std::string &begin_event_id, const std::string &end_event_id)
123 {
124 AddLineTimedEvent(text, speaker,
125 vt_common::DIALOGUE_NEXT_LINE, vt_common::DIALOGUE_NO_TIMER,
126 begin_event_id, end_event_id, std::string());
127 }
128
AddLineEventEmote(const std::string & text,MapSprite * speaker,const std::string & begin_event_id,const std::string & end_event_id,const std::string & emote_id)129 void SpriteDialogue::AddLineEventEmote(const std::string &text,
130 MapSprite *speaker,
131 const std::string &begin_event_id,
132 const std::string &end_event_id,
133 const std::string &emote_id)
134 {
135 AddLineTimedEvent(text, speaker,
136 vt_common::DIALOGUE_NEXT_LINE, vt_common::DIALOGUE_NO_TIMER,
137 begin_event_id, end_event_id, emote_id);
138 }
139
AddLineEvent(const std::string & text,MapSprite * speaker,int32_t next_line,const std::string & begin_event_id,const std::string & end_event_id)140 void SpriteDialogue::AddLineEvent(const std::string &text, MapSprite *speaker, int32_t next_line,
141 const std::string &begin_event_id, const std::string &end_event_id)
142 {
143 AddLineTimedEvent(text, speaker,
144 next_line, vt_common::DIALOGUE_NO_TIMER,
145 begin_event_id, end_event_id, std::string());
146 }
147
AddLineTimedEvent(const std::string & text,MapSprite * speaker,uint32_t display_time,const std::string & begin_event_id,const std::string & end_event_id)148 void SpriteDialogue::AddLineTimedEvent(const std::string &text, MapSprite *speaker, uint32_t display_time,
149 const std::string &begin_event_id, const std::string &end_event_id)
150 {
151 AddLineTimedEvent(text, speaker,
152 vt_common::DIALOGUE_NEXT_LINE, display_time,
153 begin_event_id, end_event_id, std::string());
154 }
155
AddLineTimedEvent(const std::string & text,MapSprite * speaker,int32_t next_line,uint32_t display_time,const std::string & begin_event_id,const std::string & end_event_id,const std::string & emote_id)156 void SpriteDialogue::AddLineTimedEvent(const std::string &text, MapSprite *speaker,
157 int32_t next_line, uint32_t display_time,
158 const std::string &begin_event_id, const std::string &end_event_id,
159 const std::string& emote_id)
160 {
161 Dialogue::AddLineTimed(text, next_line, display_time);
162 _speakers.push_back(speaker);
163 _begin_events.push_back(begin_event_id);
164 _end_events.push_back(end_event_id);
165 _emote_events.push_back(emote_id);
166 }
167
AddOption(const std::string & text)168 void SpriteDialogue::AddOption(const std::string &text)
169 {
170 AddOptionEvent(text, vt_common::DIALOGUE_NEXT_LINE, std::string());
171 }
172
AddOption(const std::string & text,int32_t next_line)173 void SpriteDialogue::AddOption(const std::string &text, int32_t next_line)
174 {
175 AddOptionEvent(text, next_line, std::string());
176 }
177
AddOptionEvent(const std::string & text,const std::string & event_id)178 void SpriteDialogue::AddOptionEvent(const std::string &text, const std::string &event_id)
179 {
180 AddOptionEvent(text, vt_common::DIALOGUE_NEXT_LINE, event_id);
181 }
182
AddOptionEvent(const std::string & text,int32_t next_line,const std::string & event_id)183 void SpriteDialogue::AddOptionEvent(const std::string &text, int32_t next_line, const std::string &event_id)
184 {
185 if(_line_count == 0) {
186 IF_PRINT_WARNING(MAP_DEBUG) << "Attempted to add an option to a dialogue with no lines" << std::endl;
187 return;
188 }
189
190 uint32_t current_line = _line_count - 1;
191
192 // If the line the options will be added to currently has no options, create a new instance of the MapDialogueOptions class to store the options in.
193 if(_options[current_line] == nullptr) {
194 _options[current_line] = new MapDialogueOptions();
195 }
196
197 MapDialogueOptions *options = dynamic_cast<MapDialogueOptions *>(_options[current_line]);
198 options->AddOptionEvent(text, next_line, event_id);
199 }
200
Validate()201 bool SpriteDialogue::Validate()
202 {
203 if(Dialogue::Validate() == false) {
204 // The CommonDialogue::Validate() call will print the appropriate warnings
205 // if debugging is enabled (common code debugging that is)
206 return false;
207 }
208
209 // Construct containers that hold all unique sprite and event ids for this dialogue
210 std::set<std::string> event_ids;
211 for(uint32_t i = 0; i < _line_count; i++) {
212 event_ids.insert(_end_events[i]);
213 }
214
215 for(std::set<std::string>::iterator it = event_ids.begin(); it != event_ids.end(); ++it) {
216 if((*it).empty())
217 continue;
218
219 if(MapMode::CurrentInstance()->GetEventSupervisor()->GetEvent(*it) == nullptr) {
220 IF_PRINT_WARNING(MAP_DEBUG) << "Validation failed for dialogue #" << _dialogue_id
221 << ": dialogue referenced invalid event with id: " << *it << std::endl;
222 return false;
223 }
224 }
225
226 return true;
227 }
228
229 } // namespace private_map
230
231 } // namespace vt_map
232