diff --git a/doc/map_syntax.dox b/doc/map_syntax.dox
index 97c2f7313..34cd2ea29 100644
--- a/doc/map_syntax.dox
+++ b/doc/map_syntax.dox
@@ -336,7 +336,7 @@ the interaction will be started only if the hero touches the south face of the e
behavior describes what happens when the player presses the action key near this entity.
There are three possible options:
-- dialog#XXX: starts a dialog with first message XXX
+- dialog#XXX: starts the dialog with id XXX
- map: calls the map script (event_hero_interaction)
- item#XXX calls the script of the item XXX (event_hero_interaction)
@@ -462,7 +462,7 @@ A shop item is a treasure one can buy in a shop in exchange for money.
Syntax of a shop item:
@verbatim
-16 layer x y entity_name treasure_name treasure_variant treasure_savegame_variable price message_id
+16 layer x y entity_name treasure_name treasure_variant treasure_savegame_variable price dialog_id
@endverbatim
treasure_name, treasure_variant and treasure_savegame_variable
@@ -476,8 +476,8 @@ and is not removed from the map.
price is the number of rupees to pay to buy the item.
-message_id is the id of the message to show when the player looks at the item.
-The message describes the item. It is automatically followed by a dialog that asks to the player
+dialog_id is the id of the dialog to show when the player looks at the item.
+The dialog describes the item. It is automatically followed by a dialog that asks to the player
if he wants to buy the item.
@section conveyor_belt Conveyor belt (17)
diff --git a/include/DialogBox.h b/include/DialogBox.h
index b15378795..b2455e215 100644
--- a/include/DialogBox.h
+++ b/include/DialogBox.h
@@ -79,10 +79,9 @@ class DialogBox {
// current message
KeysEffect::ActionKeyEffect action_key_effect_saved; /**< effect of the action key before starting the message sequence */
KeysEffect::SwordKeyEffect sword_key_effect_saved; /**< effect of the sword key before starting the message sequence */
- MessageId first_message_id; /**< id of the first message of the current sequence */
- Message *current_message; /**< the message currently shown (NULL if the dialog box is disabled) */
- MessageId current_message_id; /**< id of the message currently shown */
- std::map variables; /**< variables to display if the next messages */
+ std::string dialog_id; /**< id of the current dialog */
+ Message* current_message; /**< the message currently shown (NULL if the dialog box is disabled) */
+ std::map variables; /**< variables to display in dialogs */
Script* issuer_script; /**< the script (if any) that started the current sequence of messages */
Speed speed; /**< speed of the text */
@@ -90,7 +89,7 @@ class DialogBox {
int icon_number; /* index of the 16*16 icon displayed, or -1 if there is no icon */
bool skipped; /* true if the user has skipped the dialog */
int last_answer; /**< the answer selected in the last message sequence: 0 for the first one, 1 for the second one,
- * -1 if there was no question */
+ * -1 if there was no question */
// graphics
Surface *dialog_surface; /**< surface where the dialog is drawn*/
@@ -106,7 +105,7 @@ class DialogBox {
Rectangle icon_dst_position; /**< destination rectangle of the icon */
void set_vertical_position(VerticalPosition vertical_position);
- void show_message(const MessageId &message_id);
+ void show_message();
void show_next_message();
void close();
@@ -126,8 +125,8 @@ class DialogBox {
bool is_enabled();
// current message
- void start_dialog(const MessageId &first_message_id, Script *issuer_script = NULL,
- VerticalPosition vertical_position = POSITION_AUTO);
+ void start_dialog(const std::string& dialog_id, Script *issuer_script = NULL,
+ VerticalPosition vertical_position = POSITION_AUTO);
Speed get_speed();
void set_speed(Speed speed);
SkipMode get_skip_mode();
@@ -135,13 +134,13 @@ class DialogBox {
int get_icon_number();
void set_icon_number(int icon_number);
bool is_letter_sound_enabled();
- void set_variable(const MessageId &first_message_id, const std::string &value);
- void set_variable(const MessageId &first_message_id, int value);
+ void set_variable(const std::string& dialog_id, const std::string &value);
+ void set_variable(const std::string& dialog_id, int value);
const std::string& get_variable();
int get_last_answer();
void set_last_answer(int answer);
void key_pressed(GameControls::GameKey key);
- MessageId get_first_message_id();
+ const std::string& get_dialog_id();
bool is_finished();
bool was_skipped();
void show_all_now();
diff --git a/include/Game.h b/include/Game.h
index 79650192c..21007bb30 100755
--- a/include/Game.h
+++ b/include/Game.h
@@ -118,7 +118,7 @@ class Game: public Screen {
// current game state
bool is_paused();
- bool is_showing_message();
+ bool is_showing_dialog();
bool is_playing_transition();
bool is_showing_gameover();
bool is_suspended(); // true if at least one of the three functions above returns true
diff --git a/include/Message.h b/include/Message.h
index 80b38c728..63c6c29e7 100644
--- a/include/Message.h
+++ b/include/Message.h
@@ -21,54 +21,44 @@
#include "DialogBox.h"
/**
- * @brief A message displayed in a dialog box.
+ * @brief Lines of text displayed in a dialog box.
*
- * This class parses the message from a data file and displays it in a dialog box.
+ * This class displays three lines of text in a dialog box.
* A message is usually part of a sequence of several messages called a dialog.
*/
class Message {
private:
- // the dialog box where this message is displayed
- DialogBox *dialog_box;
-
// properties of the message
- std::string lines[3]; // the 3 lines of the message
- TextSurface *text_surfaces[3];
- bool question; // is this message a question?
- MessageId next_message_id; // id of the next message (or an empty string if this is the last message)
- MessageId next_message_id_2;
-
- int x;
- int y;
-
- void parse(MessageId message_id);
- void set_variable(const std::string &value);
-
- // current state of the display
+ DialogBox& dialog_box; /**< the dialog box where this message is displayed */
+ std::string lines[3]; /**< the 3 lines of text of the message */
+ TextSurface* text_surfaces[3]; /**< the 3 corresponding text surfaces */
+ bool question; /**< is this message a question? */
+ bool last; /**< is this message the last one of the dialog? */
- unsigned int line_index; // line currently displayed (0 to 2)
- unsigned int char_index; // index of the next character to show
- uint32_t delay;
- uint32_t next_char_date;
- bool show_all;
+ // current state of displaying
- uint32_t next_sound_date;
+ unsigned int line_index; /**< line currently displayed (0 to 2) */
+ unsigned int char_index; /**< index of the next character to show */
+ uint32_t delay; /**< delay between two characters in milliseconds */
+ uint32_t next_char_date; /**< when the next character is displayed */
+ uint32_t next_sound_date; /**< date of the next character sound */
+ bool show_all; /**< makes all text be displayed now */
void update_char_delay();
void add_character();
+ void set_variable(const std::string& value);
public:
// creation and destruction
- Message(DialogBox *dialog_box, MessageId message_id, int x, int y);
+ Message(DialogBox& dialog_box, const std::string& dialog_id, int x, int y);
~Message();
// message properties
bool is_question();
- MessageId get_next_message_id();
// message current state
bool is_finished();
diff --git a/include/Types.h b/include/Types.h
index 7b34635bd..7c541408e 100644
--- a/include/Types.h
+++ b/include/Types.h
@@ -60,11 +60,6 @@ typedef std::string SoundId;
*/
typedef std::string SpriteAnimationSetId;
-/**
- * @brief Type of the id of messages.
- */
-typedef std::string MessageId;
-
// declaration of all classes to avoid dependencies between the header files
// main classes
diff --git a/include/entities/Door.h b/include/entities/Door.h
index 1a419bec7..607a25578 100644
--- a/include/entities/Door.h
+++ b/include/entities/Door.h
@@ -47,8 +47,8 @@ class Door: public Detector {
private:
- static const std::string animations[]; /**< sprite animation name of each subtype */
- static const MessageId key_required_message_ids[]; /**< id of the message shown for each subtype */
+ static const std::string animations[]; /**< sprite animation name of each subtype */
+ static const std::string key_required_dialog_ids[]; /**< id of the dialog shown for each subtype */
// properties
Subtype subtype; /**< subtype of door */
diff --git a/include/entities/NPC.h b/include/entities/NPC.h
index 228c68193..3f97bceb2 100644
--- a/include/entities/NPC.h
+++ b/include/entities/NPC.h
@@ -67,7 +67,7 @@ class NPC: public Detector {
Subtype subtype; /**< subtpype of NPC */
Behavior behavior; /**< type of action done when the player interacts with this entity */
- MessageId message_to_show; /**< message to show when an interaction occurs, or an empty string */
+ std::string dialog_to_show; /**< dialog to show when an interaction occurs, or an empty string */
Script* script_to_call; /**< map script or item script to call when an interaction occurs, or NULL */
void initialize_sprite(SpriteAnimationSetId& sprite_name, int initial_direction);
@@ -75,8 +75,9 @@ class NPC: public Detector {
public:
- NPC(Game& game, const std::string& name, Layer layer, int x, int y, Subtype subtype,
- SpriteAnimationSetId sprite_name, int initial_direction, const std::string& behavior_string);
+ NPC(Game& game, const std::string& name, Layer layer, int x, int y,
+ Subtype subtype, SpriteAnimationSetId sprite_name,
+ int initial_direction, const std::string& behavior_string);
~NPC();
static CreationFunction parse;
diff --git a/include/entities/ShopItem.h b/include/entities/ShopItem.h
index c91c04043..f7af7e873 100644
--- a/include/entities/ShopItem.h
+++ b/include/entities/ShopItem.h
@@ -36,7 +36,7 @@ class ShopItem: public Detector {
// data
Treasure treasure; /**< the treasure the player can buy */
int price; /**< the treasure's price in rupees */
- MessageId message_id; /**< id of the message describing the shop item */
+ std::string dialog_id; /**< id of the dialog describing the shop item */
// displaying
TextSurface *price_digits; /**< the digits that show the price */
@@ -46,14 +46,14 @@ class ShopItem: public Detector {
bool is_looking_item; /**< indicates that the message describing the item is being shown */
bool is_asking_question; /**< indicates that the buy question is being shown */
- ShopItem(const std::string &name, Layer layer, int x, int y,
- const Treasure &treasure, int price, const MessageId &message_id);
+ ShopItem(const std::string& name, Layer layer, int x, int y,
+ const Treasure& treasure, int price, const std::string& dialog_id);
public:
~ShopItem();
- static ShopItem* create(Game &game, const std::string &name, Layer layer, int x, int y,
- const Treasure &treasure, int price, const MessageId &message_id);
+ static ShopItem* create(Game& game, const std::string& name, Layer layer, int x, int y,
+ const Treasure& treasure, int price, const std::string& dialog_id);
static CreationFunction parse;
EntityType get_type();
diff --git a/include/hud/HUD.h b/include/hud/HUD.h
index 04849037f..50effc5d9 100644
--- a/include/hud/HUD.h
+++ b/include/hud/HUD.h
@@ -31,7 +31,7 @@ class HUD {
int nb_elements;
HudElement *elements[16];
- bool showing_message;
+ bool showing_dialog;
void update_blinking();
diff --git a/include/lua/Script.h b/include/lua/Script.h
index 1fcdd8a0a..0d4c791b0 100644
--- a/include/lua/Script.h
+++ b/include/lua/Script.h
@@ -383,10 +383,11 @@ class Script {
bool has_played_music();
void event_map_changed(Map &map);
- void event_dialog_started(const MessageId &message_id);
- void event_dialog_finished(const MessageId &first_message_id, int answer);
+ void event_dialog_started(const std::string& dialog_id);
+ void event_dialog_finished(const std::string& dialog_id, int answer);
void event_npc_interaction(const std::string& npc_name);
- bool event_npc_interaction_item(const std::string& npc_name, const std::string& item_name, int variant);
+ bool event_npc_interaction_item(const std::string& npc_name,
+ const std::string& item_name, int variant);
void event_npc_collision_fire(const std::string &npc_name);
void do_callback(int callback_ref);
diff --git a/src/DebugKeys.cpp b/src/DebugKeys.cpp
index 5f5739e19..27ee0bc9b 100644
--- a/src/DebugKeys.cpp
+++ b/src/DebugKeys.cpp
@@ -192,7 +192,7 @@ void DebugKeys::update() {
#ifdef SOLARUS_DEBUG_KEYS
if (InputEvent::is_shift_down()) {
- if (game != NULL && game->is_showing_message()) {
+ if (game != NULL && game->is_showing_dialog()) {
game->get_dialog_box().show_all_now();
}
}
diff --git a/src/DialogBox.cpp b/src/DialogBox.cpp
index 117465bee..9f3a0b5e6 100644
--- a/src/DialogBox.cpp
+++ b/src/DialogBox.cpp
@@ -34,7 +34,8 @@
* @param game the game this dialog box belongs to
*/
DialogBox::DialogBox(Game &game):
- game(game), current_message(NULL) {
+ game(game),
+ current_message(NULL) {
// initialize the surface
dialog_surface = new Surface(320, 240);
@@ -187,46 +188,48 @@ bool DialogBox::is_letter_sound_enabled() {
}
/**
- * @brief Specifies the value of a variable that will occur in a future message.
+ * @brief Specifies the value of a variable that will occur in a dialog.
*
- * A value is expected in a message when the '$v' sequence is read.
- * You can specify only one variable at the same time per message sequence.
- * If a variable was already specified for this sequence of messages, it is replaced.
+ * A value is expected in a dialog when the '$v' sequence is read.
+ * You can specify only one variable at the same time per dialog.
+ * If a variable was already specified for this dialog, it is replaced.
*
- * @param first_message_id id of the first message of the sequence where this value will appear
+ * @param dialog_id id of the dialog where this value will appear
* @param value the value to add
*/
-void DialogBox::set_variable(const MessageId &first_message_id, const std::string &value) {
- variables[first_message_id] = value;
+void DialogBox::set_variable(const std::string& dialog_id, const std::string& value) {
+ variables[dialog_id] = value;
}
/**
- * @brief Same thing as set_variable(MessageId, string) but with an integer parameter.
+ * @brief Same thing as set_variable(string, string) but with an integer parameter.
*
* This function just converts the integer value to a string
* add calls the other function.
*
- * @param first_message_id id of the first message of the sequence where this value will appear
+ * @param dialog id id of the dialog where this value will appear
* @param value the value to set
*/
-void DialogBox::set_variable(const MessageId &first_message_id, int value) {
+void DialogBox::set_variable(const std::string& dialog_id, int value) {
+
std::ostringstream oss;
oss << value;
- set_variable(first_message_id, oss.str());
+ set_variable(dialog_id, oss.str());
}
/**
* @brief Returns the variable specified by a previous
- * call to set_variable(), for the current sequence of messages.
+ * call to set_variable(), for the current dialog.
* This function is called by
* the current message when it reads the '$v' sequence.
* @return the value of the variable
*/
const std::string& DialogBox::get_variable() {
- const std::string &value = variables[first_message_id];
+ const std::string& value = variables[dialog_id];
- Debug::check_assertion(value.size() > 0, StringConcat() << "Missing variable in message '" << current_message_id << "'");
+ Debug::check_assertion(value.size() > 0, StringConcat()
+ << "Missing variable in dialog '" << dialog_id << "'");
return value;
}
@@ -252,22 +255,23 @@ void DialogBox::set_last_answer(int answer) {
}
/**
- * @brief Starts a sequence of messages.
+ * @brief Starts a dialog.
*
* The dialog box should not be enabled already when you call this function.
*
- * @param first_message_id id of the first message of the sequence
+ * @param dialog_id of the dialog
* @param issuer_script the script that issued the request to start a dialog
* (will be notified when the dialog finishes), or NULL
* @param vertical_position vertical position where to display the dialog box (default: auto)
*/
-void DialogBox::start_dialog(const MessageId &first_message_id, Script *issuer_script,
+void DialogBox::start_dialog(const std::string& dialog_id, Script* issuer_script,
VerticalPosition vertical_position) {
- Debug::check_assertion(!is_enabled(), StringConcat() << "Cannot start message sequence '" << first_message_id << ": the dialog box is already enabled");
+ Debug::check_assertion(!is_enabled(), StringConcat() <<
+ "Cannot start dialog '" << dialog_id << ": the dialog box is already enabled");
// save the action and sword keys
- KeysEffect &keys_effect = game.get_keys_effect();
+ KeysEffect& keys_effect = game.get_keys_effect();
action_key_effect_saved = keys_effect.get_action_key_effect();
sword_key_effect_saved = keys_effect.get_sword_key_effect();
@@ -277,27 +281,26 @@ void DialogBox::start_dialog(const MessageId &first_message_id, Script *issuer_s
set_skip_mode(SKIP_NONE);
set_icon_number(-1);
this->skipped = false;
- this->first_message_id = first_message_id;
- show_message(first_message_id);
+ this->dialog_id = dialog_id;
+ show_message();
// notify the scripts
- game.get_map_script().event_dialog_started(first_message_id);
+ game.get_map_script().event_dialog_started(dialog_id);
this->issuer_script = issuer_script;
if (issuer_script != NULL) {
- issuer_script->event_dialog_started(first_message_id);
+ issuer_script->event_dialog_started(dialog_id);
}
}
/**
* @brief Shows a new message in the dialog box.
- * @param message_id id of the message to create (must be a valid id)
*/
-void DialogBox::show_message(const MessageId &message_id) {
+void DialogBox::show_message() {
// create the message
delete current_message;
- current_message = new Message(this, message_id, box_dst_position.get_x(), box_dst_position.get_y());
- current_message_id = message_id;
+ current_message = new Message(*this, dialog_id,
+ box_dst_position.get_x(), box_dst_position.get_y());
if (current_message->is_question()) {
set_last_answer(0);
@@ -326,10 +329,10 @@ void DialogBox::show_message(const MessageId &message_id) {
*/
void DialogBox::show_next_message() {
- MessageId next_message_id = current_message->get_next_message_id();
+ const std::string next_dialog_id; // TODO
- if (next_message_id != "" && next_message_id != "_unknown") {
- show_message(next_message_id);
+ if (next_dialog_id != "" && next_dialog_id != "_unknown") {
+ show_message();
}
else {
close();
@@ -351,14 +354,14 @@ void DialogBox::close() {
keys_effect.set_sword_key_effect(sword_key_effect_saved);
// notify the script if necessary
- if (!skipped && first_message_id[0] != '_') { // FIXME: remove the '_' restriction
+ if (!skipped && dialog_id[0] != '_') { // FIXME: remove the '_' restriction
// a dialog of the quest was just finished: notify the scripts
- Script &map_script = game.get_map_script();
- map_script.event_dialog_finished(first_message_id, last_answer);
+ Script& map_script = game.get_map_script();
+ map_script.event_dialog_finished(dialog_id, last_answer);
if (issuer_script != NULL && issuer_script != &map_script) {
// also notify the issuer script if different
- issuer_script->event_dialog_finished(first_message_id, last_answer);
+ issuer_script->event_dialog_finished(dialog_id, last_answer);
}
}
}
@@ -452,11 +455,11 @@ void DialogBox::show_all_now() {
}
/**
- * @brief Returns the id of the first message shown in the current dialog box sequence.
- * @return the id of the first message shown
+ * @brief Returns the id of the current dialog.
+ * @return the id of the dialog currently shown
*/
-MessageId DialogBox::get_first_message_id() {
- return first_message_id;
+const std::string& DialogBox::get_dialog_id() {
+ return dialog_id;
}
/**
@@ -503,8 +506,8 @@ void DialogBox::update() {
KeysEffect &keys_effect = game.get_keys_effect();
if (!end_message_sprite->is_animation_started()) {
- MessageId next_message_id = current_message->get_next_message_id();
- if (next_message_id != "" || current_message->is_question()) {
+ const std::string next_dialog_id; // TODO
+ if (next_dialog_id != "" || current_message->is_question()) {
end_message_sprite->set_current_animation("next");
keys_effect.set_action_key_effect(KeysEffect::ACTION_KEY_NEXT);
}
diff --git a/src/Game.cpp b/src/Game.cpp
index 8f326bb95..592b05c93 100755
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -192,7 +192,7 @@ void Game::key_pressed(GameControls::GameKey key) {
}
// is a message being shown?
- else if (is_showing_message()) {
+ else if (is_showing_dialog()) {
dialog_box->key_pressed(key);
}
@@ -376,7 +376,7 @@ void Game::update_transitions() {
void Game::update_keys_effect() {
// when the game is paused or a dialog box is shown, the sword key is not the usual one
- if (is_paused() || is_showing_message()) {
+ if (is_paused() || is_showing_dialog()) {
return; // if the game is interrupted for some other reason (e.g. a transition), let the normal sword icon
}
@@ -438,7 +438,7 @@ void Game::display(Surface *screen_surface) {
}
// display the dialog box if any
- if (is_showing_message()) {
+ if (is_showing_dialog()) {
dialog_box->display(screen_surface);
}
}
@@ -598,15 +598,15 @@ bool Game::is_playing_transition() {
* @return true if the game is suspended
*/
bool Game::is_suspended() {
- return current_map == NULL || is_paused() || is_showing_message() ||
+ return current_map == NULL || is_paused() || is_showing_dialog() ||
is_playing_transition() || is_showing_gameover() || !current_map->is_camera_fixed_on_hero();
}
/**
- * @brief Returns whether we are showing a message.
- * @return true if a message is being shown.
+ * @brief Returns whether we are showing a dialog box.
+ * @return true if a dialog box is being shown
*/
-bool Game::is_showing_message() {
+bool Game::is_showing_dialog() {
return dialog_box->is_enabled();
}
diff --git a/src/Message.cpp b/src/Message.cpp
index ece67d65e..6cc5e0154 100644
--- a/src/Message.cpp
+++ b/src/Message.cpp
@@ -41,14 +41,11 @@ static const uint32_t char_delays[3] = {
* @param x x position of the dialog box
* @param y y position of the dialog box
*/
-Message::Message(DialogBox *dialog_box, MessageId message_id, int x, int y):
- dialog_box(dialog_box), x(x), y(y) {
-
- // parse the message
- parse(message_id);
+Message::Message(DialogBox& dialog_box, const std::string& dialog_id, int x, int y):
+ dialog_box(dialog_box) {
// create the text surfaces
- int text_x = x + ((dialog_box->get_icon_number() == -1) ? 16 : 48);
+ int text_x = x + ((dialog_box.get_icon_number() == -1) ? 16 : 48);
int text_y = y - 1;
for (int i = 0; i < 3; i++) {
text_y += 13;
@@ -79,69 +76,6 @@ Message::~Message() {
}
}
-/**
- * @brief Reads the message from the data file and initializes
- * the fields accordingly.
- * @param message_id id of the message
- */
-void Message::parse(MessageId message_id) {
-
- // open the file
- std::string file_name = "text/dialogs.dat";
-
- // parse the message
- IniFile ini_file(file_name, IniFile::READ_LANGUAGE);
-
- Debug::check_assertion(ini_file.has_group(message_id), StringConcat() << "The message '" << message_id << "' does not exist");
- ini_file.set_group(message_id);
-
- // text
- lines[0] = ini_file.get_string_value("line1", "");
- lines[1] = ini_file.get_string_value("line2", "");
- lines[2] = ini_file.get_string_value("line3", "");
- for (int i = 0; i < 3; i++) {
- int size = lines[i].size();
- if (lines[i][0] == '"') {
- lines[i] = lines[i].substr(1);
- size--;
- }
- if (lines[i][size - 1] == '"') {
- lines[i] = lines[i].substr(0, size - 1);
- }
- }
-
- // icon
- int icon_number = ini_file.get_integer_value("icon", -2);
- if (icon_number != -2) {
- // if an icon number is specified (even -1)
- dialog_box->set_icon_number(icon_number);
- }
-
- // next message
- next_message_id = ini_file.get_string_value("next", "");
- next_message_id_2 = ini_file.get_string_value("next2", "");
-
- // question
- question = ini_file.get_boolean_value("question", false);
-
- // skip mode
- const std::string &skip_mode_text = ini_file.get_string_value("skip", "");
-
- if (skip_mode_text != "") { // a skip mode is specified
- DialogBox::SkipMode skip_mode;
- if (skip_mode_text == "current") {
- skip_mode = DialogBox::SKIP_CURRENT;
- }
- else if (skip_mode_text == "all") {
- skip_mode = question ? DialogBox::SKIP_CURRENT : DialogBox::SKIP_ALL;
- }
- else {
- skip_mode = DialogBox::SKIP_NONE;
- }
- dialog_box->set_skip_mode(skip_mode);
- }
-}
-
/**
* @brief Returns whether this message is a question.
* @return true if the message is a question
@@ -150,22 +84,6 @@ bool Message::is_question() {
return question;
}
-/**
- * @brief Returns the id of the next message to display.
- *
- * If this is the last message, an empty string is returned.
- *
- * @return the id of the message to display when this one is over
- */
-MessageId Message::get_next_message_id() {
-
- if (question && dialog_box->get_last_answer() == 1) {
- return next_message_id_2;
- }
-
- return next_message_id;
-}
-
/**
* @brief Returns whether the message is now completely displayed.
* @return true if the message is over
@@ -178,6 +96,7 @@ bool Message::is_finished() {
* @brief Shows all characters of the message now.
*/
void Message::show_all_now() {
+
show_all = true;
update_char_delay();
}
@@ -190,7 +109,7 @@ void Message::show_all_now() {
void Message::update_char_delay() {
if (!show_all) {
- delay = char_delays[dialog_box->get_speed()];
+ delay = char_delays[dialog_box.get_speed()];
}
else {
delay = 0;
@@ -233,24 +152,24 @@ void Message::add_character() {
case '1':
// slow
- dialog_box->set_speed(DialogBox::SPEED_SLOW);
+ dialog_box.set_speed(DialogBox::SPEED_SLOW);
update_char_delay();
break;
case '2':
// medium
- dialog_box->set_speed(DialogBox::SPEED_MEDIUM);
+ dialog_box.set_speed(DialogBox::SPEED_MEDIUM);
update_char_delay();
break;
case '3':
// fast
- dialog_box->set_speed(DialogBox::SPEED_FAST);
+ dialog_box.set_speed(DialogBox::SPEED_FAST);
update_char_delay();
break;
case 'v':
- set_variable(dialog_box->get_variable());
+ set_variable(dialog_box.get_variable());
break;
default:
@@ -277,7 +196,7 @@ void Message::add_character() {
}
uint32_t now = System::now();
- if (now >= next_sound_date && dialog_box->is_letter_sound_enabled()) {
+ if (now >= next_sound_date && dialog_box.is_letter_sound_enabled()) {
Sound::play("message_letter");
next_sound_date = now + 100;
}
@@ -288,7 +207,8 @@ void Message::add_character() {
* @brief Replaces the first occurence of "$v" by the specified value.
* @param value the value to set
*/
-void Message::set_variable(const std::string &value) {
+void Message::set_variable(const std::string& value) {
+
char_index -= 2;
lines[line_index] = lines[line_index].replace(char_index, 2, value);
}
diff --git a/src/entities/Door.cpp b/src/entities/Door.cpp
index b91acbd93..d308e49c4 100644
--- a/src/entities/Door.cpp
+++ b/src/entities/Door.cpp
@@ -38,7 +38,7 @@ const std::string Door::animations[] = {
"closed", "small_key", "small_key_block", "big_key", "boss_key", "weak", "very_weak", "", "weak_block"
};
-const MessageId Door::key_required_message_ids[] = {
+const std::string Door::key_required_dialog_ids[] = {
"", "_small_key_required", "_small_key_required", "_big_key_required", "_boss_key_required", "", "", "", ""
};
@@ -53,7 +53,7 @@ const MessageId Door::key_required_message_ids[] = {
* @param savegame_variable variable where the door's state is saved
* (can be -1 for the subtype CLOSED)
*/
-Door::Door(const std::string &name, Layer layer, int x, int y,
+Door::Door(const std::string& name, Layer layer, int x, int y,
int direction, Subtype subtype, int savegame_variable):
Detector(COLLISION_FACING_POINT | COLLISION_SPRITE, name, layer, x, y, 16, 16),
subtype(subtype),
@@ -393,7 +393,7 @@ void Door::action_key_pressed() {
}
else {
Sound::play("wrong");
- get_dialog_box().start_dialog(key_required_message_ids[subtype]);
+ get_dialog_box().start_dialog(key_required_dialog_ids[subtype]);
}
}
}
diff --git a/src/entities/NPC.cpp b/src/entities/NPC.cpp
index d7c413035..dad83dac9 100644
--- a/src/entities/NPC.cpp
+++ b/src/entities/NPC.cpp
@@ -44,7 +44,7 @@
* @param direction for a generalized NPC: direction for which the interactions are allowed
* (0 to 4, or -1 for any direction), for a usual NPC: initial direction of the NPC's sprite
* @param behavior_string indicates what happens when the hero interacts with this NPC:
- * "message#XXX" to start the dialog XXX, "map" to call the map script
+ * "dialog#XXX" to start the dialog XXX, "map" to call the map script
* (with an event_hero_interaction() call) or "item#XXX" to call the script
* of item XXX (with an event_hero_interaction() call)
*/
@@ -53,7 +53,7 @@ NPC::NPC(Game& game, const std::string& name, Layer layer, int x, int y,
int direction, const std::string& behavior_string):
Detector(COLLISION_FACING_POINT | COLLISION_RECTANGLE, name, layer, x, y, 0, 0),
subtype(subtype),
- message_to_show(""),
+ dialog_to_show(""),
script_to_call(NULL) {
initialize_sprite(sprite_name, direction);
@@ -73,7 +73,7 @@ NPC::NPC(Game& game, const std::string& name, Layer layer, int x, int y,
}
else if (behavior_string.substr(0, 7) == "dialog#") {
behavior = BEHAVIOR_DIALOG;
- message_to_show = behavior_string.substr(7);
+ dialog_to_show = behavior_string.substr(7);
}
else {
Debug::die(StringConcat() << "Invalid behavior string for interactive entity '" << name
@@ -282,7 +282,7 @@ void NPC::action_key_pressed() {
if (effect != KeysEffect::ACTION_KEY_LIFT) {
// start the normal behavior
if (behavior == BEHAVIOR_DIALOG) {
- get_dialog_box().start_dialog(message_to_show);
+ get_dialog_box().start_dialog(dialog_to_show);
}
else {
call_script_hero_interaction();
diff --git a/src/entities/PickableItem.cpp b/src/entities/PickableItem.cpp
index cb2d57815..29f2c9d5e 100644
--- a/src/entities/PickableItem.cpp
+++ b/src/entities/PickableItem.cpp
@@ -282,7 +282,7 @@ void PickableItem::notify_collision(MapEntity &entity_overlapping, CollisionMode
if (entity_overlapping.is_hero()
&& can_be_picked
- && !get_game().is_showing_message()) {
+ && !get_game().is_showing_dialog()) {
remove_from_map();
give_item_to_player();
}
diff --git a/src/entities/ShopItem.cpp b/src/entities/ShopItem.cpp
index 61ece802e..2049e6ffb 100644
--- a/src/entities/ShopItem.cpp
+++ b/src/entities/ShopItem.cpp
@@ -40,13 +40,16 @@
* @param y y coordinate of the entity to create
* @param treasure the treasure that the hero can buy (will be deleted automatically)
* @param price the treasure's price in rupees
- * @param message_id id of the message describing the item when the player watches it
+ * @param dialog_id id of the dialog describing the item when the player watches it
*/
-ShopItem::ShopItem(const std::string &name, Layer layer, int x, int y,
- const Treasure &treasure, int price, const MessageId &message_id):
+ShopItem::ShopItem(const std::string& name, Layer layer, int x, int y,
+ const Treasure& treasure, int price, const std::string& dialog_id):
Detector(COLLISION_FACING_POINT, name, layer, x, y, 32, 32),
- treasure(treasure), price(price), message_id(message_id),
- is_looking_item(false), is_asking_question(false) {
+ treasure(treasure),
+ price(price),
+ dialog_id(dialog_id),
+ is_looking_item(false),
+ is_asking_question(false) {
std::ostringstream oss;
oss << price;
@@ -61,6 +64,7 @@ ShopItem::ShopItem(const std::string &name, Layer layer, int x, int y,
* @brief Destructor.
*/
ShopItem::~ShopItem() {
+
delete price_digits;
delete rupee_icon_sprite;
}
@@ -77,22 +81,22 @@ ShopItem::~ShopItem() {
* @param y y coordinate of the entity
* @return the instance created
*/
-MapEntity* ShopItem::parse(Game &game, std::istream &is, Layer layer, int x, int y) {
+MapEntity* ShopItem::parse(Game& game, std::istream& is, Layer layer, int x, int y) {
std::string name, treasure_name;
int treasure_variant, treasure_savegame_variable, price;
- MessageId message_id;
+ std::string dialog_id;
FileTools::read(is, name);
FileTools::read(is, treasure_name);
FileTools::read(is, treasure_variant);
FileTools::read(is, treasure_savegame_variable);
FileTools::read(is, price);
- FileTools::read(is, message_id);
+ FileTools::read(is, dialog_id);
return create(game, name, Layer(layer), x, y,
Treasure(game, treasure_name, treasure_variant, treasure_savegame_variable),
- price, message_id);
+ price, dialog_id);
}
/**
@@ -104,18 +108,18 @@ MapEntity* ShopItem::parse(Game &game, std::istream &is, Layer layer, int x, int
* @param y y coordinate of the entity to create
* @param treasure the treasure that the hero can buy
* @param price the treasure's price in rupees
- * @param message_id id of the message describing the item when the player watches it
+ * @param dialog_id id of the dialog describing the item when the player watches it
* @return the shop item created, or NULL if it is already bought
*/
-ShopItem* ShopItem::create(Game &game, const std::string &name, Layer layer, int x, int y,
- const Treasure &treasure, int price, const MessageId &message_id) {
+ShopItem* ShopItem::create(Game& game, const std::string& name, Layer layer, int x, int y,
+ const Treasure &treasure, int price, const std::string& dialog_id) {
// see if the item is not already bought
if (treasure.is_found()) {
return NULL;
}
- return new ShopItem(name, layer, x, y, treasure, price, message_id);
+ return new ShopItem(name, layer, x, y, treasure, price, dialog_id);
}
/**
@@ -161,7 +165,7 @@ void ShopItem::notify_collision(MapEntity &entity_overlapping, CollisionMode col
Hero &hero = (Hero&) entity_overlapping;
if (get_keys_effect().get_action_key_effect() == KeysEffect::ACTION_KEY_NONE
- && hero.is_free()) {
+ && hero.is_free()) {
// we show the 'look' icon
get_keys_effect().set_action_key_effect(KeysEffect::ACTION_KEY_LOOK);
@@ -181,7 +185,7 @@ void ShopItem::action_key_pressed() {
if (get_hero().is_free()
&& get_keys_effect().get_action_key_effect() == KeysEffect::ACTION_KEY_LOOK) {
- get_dialog_box().start_dialog(message_id);
+ get_dialog_box().start_dialog(dialog_id);
is_looking_item = true;
}
}
@@ -191,16 +195,16 @@ void ShopItem::action_key_pressed() {
*/
void ShopItem::update() {
- if (is_looking_item && !get_game().is_showing_message()) {
+ if (is_looking_item && !get_game().is_showing_dialog()) {
// the description message has just finished
- std::string question_message_id = "_shop.question";
- get_dialog_box().start_dialog(question_message_id);
- get_dialog_box().set_variable(question_message_id, price);
+ const std::string question_dialog_id = "_shop.question";
+ get_dialog_box().start_dialog(question_dialog_id);
+ get_dialog_box().set_variable(question_dialog_id, price);
is_asking_question = true;
is_looking_item = false;
}
- else if (is_asking_question && !get_game().is_showing_message()) {
+ else if (is_asking_question && !get_game().is_showing_dialog()) {
// the question has just finished
is_asking_question = false;
@@ -209,17 +213,17 @@ void ShopItem::update() {
if (answer == 0) {
// the player wants to buy the item
- Equipment &equipment = get_equipment();
+ Equipment& equipment = get_equipment();
if (equipment.get_money() < price) {
- // not enough rupees
- Sound::play("wrong");
- get_dialog_box().start_dialog("_shop.not_enough_money");
+ // not enough rupees
+ Sound::play("wrong");
+ get_dialog_box().start_dialog("_shop.not_enough_money");
}
else if (equipment.has_item_maximum(treasure.get_item_name())) {
- // the player already has the maximum amount of this item
- Sound::play("wrong");
- get_dialog_box().start_dialog("_shop.amount_full");
+ // the player already has the maximum amount of this item
+ Sound::play("wrong");
+ get_dialog_box().start_dialog("_shop.amount_full");
}
else {
diff --git a/src/hero/TreasureState.cpp b/src/hero/TreasureState.cpp
index 7c199a2cd..77b75fdaf 100644
--- a/src/hero/TreasureState.cpp
+++ b/src/hero/TreasureState.cpp
@@ -89,7 +89,7 @@ void Hero::TreasureState::update() {
State::update();
- if (!get_game().is_showing_message()) {
+ if (!get_game().is_showing_dialog()) {
// the treasure's dialog is over: if the treasure was a tunic,
// a sword or a shield, we have to reload the hero's sprites now
diff --git a/src/hud/HUD.cpp b/src/hud/HUD.cpp
index 74bdaa667..bd5c7dbe9 100644
--- a/src/hud/HUD.cpp
+++ b/src/hud/HUD.cpp
@@ -32,7 +32,9 @@
* @param game the current game (cannot be NULL)
*/
HUD::HUD(Game &game):
- game(game), nb_elements(0), showing_message(false) {
+ game(game),
+ nb_elements(0),
+ showing_dialog(false) {
elements[nb_elements++] = new HeartsView(game, 216, 6);
elements[nb_elements++] = new RupeesCounter(game, 8, 220);
@@ -110,21 +112,21 @@ void HUD::update_blinking() {
*/
void HUD::update() {
- // detect when the game is showing a message
- if (game.is_showing_message() && !showing_message) {
- showing_message = true;
+ // detect when the game is showing a dialog
+ if (game.is_showing_dialog() && !showing_dialog) {
+ showing_dialog = true;
- // a message is shown: hide or move the top-left icons
+ // a dialog is shown: hide or move the top-left icons
elements[3]->set_visible(false); // item 0
elements[4]->set_visible(false); // item 1
elements[6]->set_visible(false); // pause icon
elements[5]->set_position(-11, 17); // sword icon
elements[7]->set_position(-11, 43); // action icon
}
- else if (!game.is_showing_message()) {
+ else if (!game.is_showing_dialog()) {
- if (showing_message) {
- showing_message = false;
+ if (showing_dialog) {
+ showing_dialog = false;
// a message is finished: restore the top-left icons
elements[3]->set_visible(true); // item 0
diff --git a/src/lua/MapAPI.cpp b/src/lua/MapAPI.cpp
index 178a458e9..0c2b04ef6 100644
--- a/src/lua/MapAPI.cpp
+++ b/src/lua/MapAPI.cpp
@@ -40,45 +40,40 @@
#include
/**
- * @brief Creates a dialog box and starts displaying a message.
+ * @brief Shows the dialog box and starts displaying a dialog.
*
- * If the message is followed by other messages, they are also
- * displayed.
- * If the message (or one of its next messages) contains a variable,
- * then you have to call dialog_set_variable() to specify its value.
+ * If the dialog contains a variable,
+ * then you have to call sol.map.dialog_set_variable() to specify its value.
*
- * - Argument 1 (string): id of the message to display
+ * - Argument 1 (string): id of the dialog to display
*
* @param l the Lua context that is calling this function
*/
-int Script::map_api_dialog_start(lua_State *l) {
+int Script::map_api_dialog_start(lua_State* l) {
Script& script = get_script(l, 1);
- const std::string &message_id = luaL_checkstring(l, 1);
+ const std::string& dialog_id = luaL_checkstring(l, 1);
- script.get_game().get_dialog_box().start_dialog(message_id, &script);
+ script.get_game().get_dialog_box().start_dialog(dialog_id, &script);
return 0;
}
/**
- * @brief Sets the value of the variable in a diabog.
+ * @brief Sets the value of the variable in a dialog.
*
- * The function has to be called after the dialog box is created,
- * i.e. after calling dialog_start().
- *
- * - Argument 1 (string): id of the message containing the variable
+ * - Argument 1 (string): id of the dialog containing the variable
* - Argument 2 (string): value of the variable
*
* @param l the Lua context that is calling this function
*/
-int Script::map_api_dialog_set_variable(lua_State *l) {
+int Script::map_api_dialog_set_variable(lua_State* l) {
Script& script = get_script(l, 2);
- const MessageId &message_id = luaL_checkstring(l, 1);
- const std::string &value = luaL_checkstring(l, 2);
+ const std::string& dialog_id = luaL_checkstring(l, 1);
+ const std::string& value = luaL_checkstring(l, 2);
- script.get_game().get_dialog_box().set_variable(message_id, value);
+ script.get_game().get_dialog_box().set_variable(dialog_id, value);
return 0;
}
diff --git a/src/lua/Script.cpp b/src/lua/Script.cpp
index 3e3a96ce1..e52203be7 100644
--- a/src/lua/Script.cpp
+++ b/src/lua/Script.cpp
@@ -869,7 +869,7 @@ bool Script::is_new_timer_suspended(void) {
if (apis_enabled && GAME_API) {
// start the timer even if the game is suspended (e.g. a timer started during a camera movement)
// except when it is suspended because of a dialog box
- return get_game().is_showing_message();
+ return get_game().is_showing_dialog();
}
return false;
@@ -974,28 +974,28 @@ void Script::event_map_changed(Map &map) {
/**
* @brief Notifies the script that a dialog has just started to be displayed
* in the dialog box.
- * @param message_id id of the first message in this dialog
+ * @param dialog_id id of the dialog
*/
-void Script::event_dialog_started(const MessageId &message_id) {
+void Script::event_dialog_started(const std::string& dialog_id) {
- notify_script("event_dialog_started", "s", message_id.c_str());
+ notify_script("event_dialog_started", "s", dialog_id.c_str());
}
/**
* @brief Notifies the script that the dialog box has just finished.
*
- * This function is called when the last message of a dialog is finished.
+ * This function is called when the last group of 3 lines of a dialog is
+ * finished.
* The dialog box has just been closed but the game is still suspended.
* Note that this event is not called if the dialog was skipped.
*
- * @param first_message_id id of the first message in the dialog
- * that has just finished
+ * @param dialog_id id of the dialog that has just finished
* @param answer the answer selected by the player: 0 for the first one,
* 1 for the second one, -1 if there was no question
*/
-void Script::event_dialog_finished(const MessageId &first_message_id, int answer) {
+void Script::event_dialog_finished(const std::string& dialog_id, int answer) {
- notify_script("event_dialog_finished", "si", first_message_id.c_str(), answer);
+ notify_script("event_dialog_finished", "si", dialog_id.c_str(), answer);
}
/**