/** * @brief Shows a new group of 3 lines in the dialog box, if any. */ void DialogBox::show_more_lines() { if (!has_more_lines()) { show_next_dialog(); return; } // hide the action icon and change the sword icon KeysEffect& keys_effect = game.get_keys_effect(); keys_effect.set_action_key_effect(KeysEffect::ACTION_KEY_NONE); if (skip_mode != Dialog::SKIP_NONE) { keys_effect.set_sword_key_effect(KeysEffect::SWORD_KEY_SKIP); keys_effect.set_action_key_effect(KeysEffect::ACTION_KEY_NEXT); } else { keys_effect.set_sword_key_effect(KeysEffect::SWORD_KEY_HIDDEN); } // hide the bottom arrow end_lines_sprite.stop_animation(); // prepare the lines int text_x = box_dst_position.get_x() + ((icon_number == -1) ? 16 : 48); int text_y = box_dst_position.get_y() - 1; for (int i = 0; i < nb_visible_lines; i++) { text_y += 13; line_surfaces[i]->set_x(text_x); line_surfaces[i]->set_y(text_y); line_surfaces[i]->set_text(""); if (has_more_lines()) { lines[i] = *line_it; line_it++; } else { lines[i] = ""; } } if (dialog.is_question() && !has_more_lines()) { text_x += 24; line_surfaces[nb_visible_lines - 2]->set_x(text_x); line_surfaces[nb_visible_lines - 1]->set_x(text_x); } // initialize the lines this->line_index = 0; this->char_index = 0; this->next_char_date = this->next_sound_date = System::now(); }
/** * \brief Shows a new group of 3 lines (if possible) in the built-in * dialog box. */ void DialogBoxSystem::show_more_lines() { // This function is only called in the built-in case. Debug::check_assertion(built_in, "This dialog box is not the built-in one"); if (!has_more_lines()) { ScopedLuaRef status_ref; if (is_question) { // Send the answer to the callback. LuaContext& lua_context = game.get_lua_context(); lua_pushboolean(lua_context.get_internal_state(), selected_first_answer); status_ref = lua_context.create_ref(); } close(status_ref); return; } KeysEffect& keys_effect = game.get_keys_effect(); keys_effect.set_action_key_effect(KeysEffect::ACTION_KEY_NEXT); // Prepare the 3 lines. int text_x = text_position.x; int text_y = text_position.y; for (int i = 0; i < nb_visible_lines; i++) { text_y += 16; line_surfaces[i]->set_x(text_x); line_surfaces[i]->set_y(text_y); line_surfaces[i]->set_text_color(Color::white); if (has_more_lines()) { line_surfaces[i]->set_text(*remaining_lines.begin()); remaining_lines.pop_front(); } else { line_surfaces[i]->set_text(""); } } if (built_in && is_question && !has_more_lines()) { // If the dialog is a question, we assume that the last group of 3 lines // are the question and the two possible answers. // Remember that this is only the case of the built-in dialog box: // if the user needs something more elaborate, he should make his own // dialog box in Lua. this->selected_first_answer = true; line_surfaces[nb_visible_lines - 2]->set_text_color(Color::yellow); } }
/** * \brief This function is called by the game when a command is pressed * while a dialog is active. * * Nothing happens if the dialog is handled in Lua. * * \param command The command pressed. * \return \c true if the command was handled (that is, if the dialog box * is active and is the built-in one). */ bool DialogBoxSystem::notify_command_pressed(GameCommand command) { if (!is_enabled()) { return false; } if (!built_in) { // The dialog box is handled by a Lua script. return false; } if (command == GameCommand::ACTION) { show_more_lines(); } else if (command == GameCommand::UP || command == GameCommand::DOWN) { if (is_question && !has_more_lines()) { // Switch the selected answer. selected_first_answer = !selected_first_answer; int selected_line_index = selected_first_answer ? 1 : 2; for (int i = 0; i < nb_visible_lines; i++) { line_surfaces[i]->set_text_color(Color::white); } line_surfaces[selected_line_index]->set_text_color(Color::yellow); } } return true; }
/** * @brief Updates the dialog box. * * This function is called repeatedly by the game * while the dialog box exists. */ void DialogBox::update() { if (!is_enabled()) { return; // nothing to update } // update the text displaying update_lines(); // handle the end of the visible lines if (is_full()) { // update the message end arrow end_lines_sprite.update(); // show the appropriate action icon KeysEffect& keys_effect = game.get_keys_effect(); if (!end_lines_sprite.is_animation_started()) { if (has_more_lines() || dialog.has_next() || dialog.is_question()) { end_lines_sprite.set_current_animation("next"); keys_effect.set_action_key_effect(KeysEffect::ACTION_KEY_NEXT); } else { keys_effect.set_action_key_effect(KeysEffect::ACTION_KEY_RETURN); end_lines_sprite.set_current_animation("last"); } keys_effect.set_sword_key_effect(KeysEffect::SWORD_KEY_HIDDEN); Sound::play("message_end"); } } }
/** * @brief This function is called when the user pressed the up or down key. */ void DialogBox::up_or_down_key_pressed() { if (dialog.is_question() && !has_more_lines() && is_full()) { // switch the answer last_answer = 1 - last_answer; question_dst_position.set_y( box_dst_position.get_y() + ((last_answer == 0) ? 27 : 40)); Sound::play("cursor"); } }
/** * @brief Displays the dialog box on a surface. * @param destination_surface the surface */ void DialogBox::display(Surface* destination_surface) { int x = box_dst_position.get_x(); int y = box_dst_position.get_y(); dialog_surface.fill_with_color(Color::get_black()); if (style == STYLE_WITHOUT_FRAME) { // display a dark rectangle destination_surface->fill_with_color(Color::get_black(), box_dst_position); } else { // display the dialog box box_img.blit(box_src_position, &dialog_surface, box_dst_position); } // display the text for (int i = 0; i < nb_visible_lines; i++) { line_surfaces[i]->display(&dialog_surface); } // display the icon if (icon_number != -1) { Rectangle src_position(0, 0, 16, 16); src_position.set_xy(16 * (icon_number % 10), 16 * (icon_number / 10)); icons_img.blit(src_position, &dialog_surface, icon_dst_position); question_dst_position.set_x(x + 50); } else { question_dst_position.set_x(x + 18); } // display the question arrow if (dialog.is_question() && is_full() && !has_more_lines()) { box_img.blit(question_src_position, &dialog_surface, question_dst_position); } // display the end message arrow if (is_full()) { end_lines_sprite.display(&dialog_surface, x + 103, y + 56); } // final blit dialog_surface.blit(destination_surface); }