mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-21 20:44:24 +00:00
Merge pull request #5186 from Vultraz/outro_changes
[Proposal] Extended Outro dialog with campaign-specific credits
This commit is contained in:
commit
1ec585a203
@ -24,19 +24,29 @@
|
||||
[/rectangle]
|
||||
|
||||
[text]
|
||||
x = {GUI__TEXT_HORIZONTALLY_CENTRED}
|
||||
x = 0
|
||||
y = {GUI__TEXT_VERTICALLY_CENTRED}
|
||||
w = "(width)"
|
||||
h = "(text_height)"
|
||||
maximum_width = "(width)"
|
||||
|
||||
font_size = 100
|
||||
font_size = 80
|
||||
font_family = "script"
|
||||
|
||||
color = "([215, 215, 215, min(ceil(as_decimal(fade_step * 25.5)), 255)])"
|
||||
|
||||
text = "(outro_text)"
|
||||
text_markup = true
|
||||
text_alignment = "center"
|
||||
[/text]
|
||||
|
||||
[text]
|
||||
x = "(screen_width - text_width - 20)"
|
||||
y = "(screen_height - text_height - 20)"
|
||||
w = "(text_width)"
|
||||
h = "(text_height)"
|
||||
font_size = {GUI_FONT_SIZE_DEFAULT}
|
||||
text = _ "Press ESC to skip"
|
||||
[/text]
|
||||
|
||||
[/draw]
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "about.hpp"
|
||||
|
||||
#include "config.hpp"
|
||||
#include "font/pango/escape.hpp"
|
||||
#include "game_config_view.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
@ -81,7 +82,7 @@ credits_group::about_group::about_group(const config& cfg)
|
||||
names.reserve(cfg.child_count("entry"));
|
||||
|
||||
for(const config& entry : cfg.child_range("entry")) {
|
||||
names.emplace_back(entry["name"].str(), entry["comment"].str());
|
||||
names.emplace_back(font::escape_text(entry["name"].str()), font::escape_text(entry["comment"].str()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,6 +96,12 @@ const credits_data& get_credits_data()
|
||||
return parsed_credits_data;
|
||||
}
|
||||
|
||||
credits_data::const_iterator get_campaign_credits(const std::string& campaign)
|
||||
{
|
||||
return std::find_if(parsed_credits_data.begin(), parsed_credits_data.end(),
|
||||
[&campaign](const credits_group& group) { return group.id == campaign; });
|
||||
}
|
||||
|
||||
std::vector<std::string> get_background_images(const std::string& campaign)
|
||||
{
|
||||
if(!campaign.empty() && !images_campaigns[campaign].empty()) {
|
||||
|
@ -53,16 +53,16 @@ struct credits_group
|
||||
|
||||
using credits_data = std::vector<credits_group>;
|
||||
|
||||
/**
|
||||
* General getter methods for the credits config and image lists by campaign id
|
||||
*/
|
||||
/** Gets all credits data. */
|
||||
const credits_data& get_credits_data();
|
||||
|
||||
/** Gets credits for a given campaign. */
|
||||
credits_data::const_iterator get_campaign_credits(const std::string& campaign);
|
||||
|
||||
/** Gets credit background images for a given campaaign. */
|
||||
std::vector<std::string> get_background_images(const std::string& campaign);
|
||||
|
||||
/**
|
||||
* Regenerates the credits config
|
||||
*/
|
||||
/** Regenerates the credits data. */
|
||||
void set_about(const game_config_view& cfg);
|
||||
|
||||
} // namespace about
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "game_config_manager.hpp" // for game_config_manager
|
||||
#include "generators/map_generator.hpp" // for mapgen_exception
|
||||
#include "gettext.hpp" // for _
|
||||
#include "gui/dialogs/end_credits.hpp"
|
||||
#include "gui/dialogs/language_selection.hpp" // for language_selection
|
||||
#include "gui/dialogs/loading_screen.hpp"
|
||||
#include "gui/dialogs/message.hpp" //for show error message
|
||||
@ -1031,10 +1030,6 @@ void game_launcher::launch_game(RELOAD_GAME_DATA reload)
|
||||
preferences::add_completed_campaign(state_.classification().campaign, state_.classification().difficulty);
|
||||
|
||||
gui2::dialogs::outro::display(state_.classification());
|
||||
|
||||
if(state_.classification().end_credits) {
|
||||
gui2::dialogs::end_credits::display(state_.classification().campaign);
|
||||
}
|
||||
}
|
||||
} catch (const savegame::load_game_exception &e) {
|
||||
load_data_.reset(new savegame::load_game_metadata(std::move(e.data_)));
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "gui/dialogs/outro.hpp"
|
||||
|
||||
#include "about.hpp"
|
||||
#include "formula/variant.hpp"
|
||||
#include "game_classification.hpp"
|
||||
#include "gettext.hpp"
|
||||
@ -31,46 +32,72 @@ namespace dialogs
|
||||
REGISTER_DIALOG(outro)
|
||||
|
||||
outro::outro(const game_classification& info)
|
||||
: text_(info.end_text)
|
||||
: text_()
|
||||
, current_text_()
|
||||
, duration_(info.end_text_duration)
|
||||
, fade_step_(0)
|
||||
, fading_in_(true)
|
||||
, timer_id_(0)
|
||||
, next_draw_(0)
|
||||
{
|
||||
if(text_.empty()) {
|
||||
text_ = _("The End");
|
||||
if(!info.end_text.empty()) {
|
||||
text_.push_back(info.end_text);
|
||||
} else {
|
||||
text_.push_back(_("The End"));
|
||||
}
|
||||
|
||||
text_.push_back("<span size='large'>" + info.campaign_name + "</span>");
|
||||
|
||||
// We only show the end text and the title if credits were turned off
|
||||
if(info.end_credits) {
|
||||
for(const auto& about : about::get_campaign_credits(info.campaign)->sections) {
|
||||
if(about.names.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Split the names into chunks of 5. Use float for proper ceil function!
|
||||
static const float chunk_size = 5.0;
|
||||
|
||||
const unsigned num_names = about.names.size();
|
||||
const unsigned num_chunks = std::ceil(num_names / chunk_size);
|
||||
|
||||
for(std::size_t i = 0; i < num_chunks; ++i) {
|
||||
std::stringstream ss;
|
||||
|
||||
// Only include section title on first chunk
|
||||
if(i == 0) {
|
||||
ss << about.title << "\n\n";
|
||||
}
|
||||
|
||||
for(std::size_t k = i * chunk_size; k < std::min<unsigned>((i + 1) * chunk_size, num_names); ++k) {
|
||||
ss << "<span size='xx-small'>" << about.names[k].first << "</span>\n";
|
||||
}
|
||||
|
||||
// Clean up the trailing newline
|
||||
std::string section_text = ss.str();
|
||||
section_text.pop_back();
|
||||
|
||||
text_.push_back(std::move(section_text));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current_text_ = text_.begin();
|
||||
|
||||
if(!duration_) {
|
||||
duration_ = 3500;
|
||||
duration_ = 3500; // 3.5 seconds
|
||||
}
|
||||
}
|
||||
|
||||
void outro::pre_show(window& window)
|
||||
{
|
||||
window.set_enter_disabled(true);
|
||||
window.get_canvas(0).set_variable("outro_text", wfl::variant(text_));
|
||||
window.get_canvas(0).set_variable("outro_text", wfl::variant(*current_text_));
|
||||
|
||||
connect_signal_on_draw(window, std::bind(&outro::draw_callback, this, std::ref(window)));
|
||||
|
||||
set_next_draw();
|
||||
}
|
||||
|
||||
void outro::set_next_draw()
|
||||
{
|
||||
/* The UI is rendered at approximately 50 FPS - 1 frame every 20 ms - meaning fading progresses every 3 frames.
|
||||
* TODO: not sure if 60 is a better value in that case?
|
||||
*/
|
||||
next_draw_ = SDL_GetTicks() + 60;
|
||||
}
|
||||
|
||||
void outro::draw_callback(window& window)
|
||||
{
|
||||
if(SDL_GetTicks() < next_draw_) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we've faded fully in...
|
||||
*
|
||||
* NOTE: we want fading to take around half a second. Given this function runs about every 3 frames, we
|
||||
@ -86,13 +113,27 @@ void outro::draw_callback(window& window)
|
||||
return;
|
||||
}
|
||||
|
||||
canvas& window_canvas = window.get_canvas(0);
|
||||
|
||||
// If we've faded fully out...
|
||||
if(!fading_in_ && fade_step_ < 0) {
|
||||
window.close();
|
||||
return;
|
||||
}
|
||||
std::advance(current_text_, 1);
|
||||
|
||||
canvas& window_canvas = window.get_canvas(0);
|
||||
// ...and we've just showed the last text bit, close the window.
|
||||
if(current_text_ == text_.end()) {
|
||||
window.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// ...else show the next bit.
|
||||
window_canvas.set_variable("outro_text", wfl::variant(*current_text_));
|
||||
|
||||
fading_in_ = true;
|
||||
fade_step_ = 0;
|
||||
|
||||
remove_timer(timer_id_);
|
||||
timer_id_ = 0;
|
||||
}
|
||||
|
||||
window_canvas.set_variable("fade_step", wfl::variant(fade_step_));
|
||||
window_canvas.set_is_dirty(true);
|
||||
@ -104,8 +145,6 @@ void outro::draw_callback(window& window)
|
||||
} else {
|
||||
fade_step_--;
|
||||
}
|
||||
|
||||
set_next_draw();
|
||||
}
|
||||
|
||||
void outro::post_show(window& /*window*/)
|
||||
|
@ -49,11 +49,10 @@ private:
|
||||
/** Inherited from modal_dialog. */
|
||||
virtual void post_show(window& window) override;
|
||||
|
||||
void set_next_draw();
|
||||
|
||||
void draw_callback(window& window);
|
||||
|
||||
std::string text_;
|
||||
std::vector<std::string> text_;
|
||||
std::vector<std::string>::iterator current_text_;
|
||||
|
||||
unsigned int duration_;
|
||||
int fade_step_;
|
||||
@ -61,7 +60,6 @@ private:
|
||||
bool fading_in_;
|
||||
|
||||
std::size_t timer_id_;
|
||||
std::size_t next_draw_;
|
||||
};
|
||||
|
||||
} // namespace dialogs
|
||||
|
Loading…
x
Reference in New Issue
Block a user