From 3e0030c75dcf2981cdba47a4e1de5ea9a6bbace2 Mon Sep 17 00:00:00 2001 From: MatusGuy Date: Tue, 13 Aug 2024 09:01:51 +0100 Subject: [PATCH 1/5] Fix broken tux santa sprite (how did this slip in here) --- src/supertux/levelintro.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/supertux/levelintro.cpp b/src/supertux/levelintro.cpp index b21eb3fb8c3..16c4d58000b 100644 --- a/src/supertux/levelintro.cpp +++ b/src/supertux/levelintro.cpp @@ -234,16 +234,17 @@ LevelIntro::push_player() if (m_player_status.bonus[i] == FIRE_BONUS && g_config->christmas_mode) { m_player_sprite[i]->set_action("big-walk-right"); - m_santa_sprite[i]->set_action("santa-walk-right"); + m_santa_sprite[i]->set_action("default"); } else { m_player_sprite[i]->set_action(m_player_status.get_bonus_prefix(i) + "-walk-right"); } + m_player_sprite_jump_timer[i]->start(graphicsRandom.randf(5,10)); /* Set Tux powerup sprite action */ - m_santa_sprite[i]->set_action(m_player_sprite[i]->get_action()); + //m_santa_sprite[i]->set_action(m_player_sprite[i]->get_action()); } void From 2d929412210765aa81ab417ecbf09703ffccc0e8 Mon Sep 17 00:00:00 2001 From: Vankata453 <78196474+Vankata453@users.noreply.github.com> Date: Thu, 15 Aug 2024 12:55:24 +0300 Subject: [PATCH 2/5] Error handler: Print fatal exceptions to command line --- src/supertux/error_handler.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/supertux/error_handler.cpp b/src/supertux/error_handler.cpp index 9cc7d041292..5530c6ef4f5 100644 --- a/src/supertux/error_handler.cpp +++ b/src/supertux/error_handler.cpp @@ -290,16 +290,9 @@ ErrorHandler::error_dialog_crash(const std::string& stacktrace) void ErrorHandler::error_dialog_exception(const std::string& exception) { - std::stringstream stream; + char msg[] = "SuperTux has encountered a fatal exception!"; - stream << "SuperTux has encountered a fatal exception!"; - - if (!exception.empty()) - { - stream << "\n\n" << exception; - } - - std::string msg = stream.str(); + std::cerr << msg << "\n\n" << exception << std::endl; SDL_MessageBoxButtonData btns[] = { #ifdef WIN32 @@ -320,7 +313,7 @@ ErrorHandler::error_dialog_exception(const std::string& exception) SDL_MESSAGEBOX_ERROR, // flags nullptr, // window "Error", // title - msg.c_str(), // message + msg, // message SDL_arraysize(btns), // numbuttons btns, // buttons nullptr // colorscheme From eacdc116584b93cf78d456d27893c8c6a9ab0119 Mon Sep 17 00:00:00 2001 From: Vankata453 <78196474+Vankata453@users.noreply.github.com> Date: Thu, 15 Aug 2024 12:59:48 +0300 Subject: [PATCH 3/5] Fix Windows compilation after 2d92941 --- src/supertux/error_handler.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/supertux/error_handler.cpp b/src/supertux/error_handler.cpp index 5530c6ef4f5..8ba48b38309 100644 --- a/src/supertux/error_handler.cpp +++ b/src/supertux/error_handler.cpp @@ -325,9 +325,7 @@ ErrorHandler::error_dialog_exception(const std::string& exception) #ifdef WIN32 if (resultbtn == 0) { - // Repurpose the stream. - stream.str(""); - + std::stringstream stream; stream << SDL_GetPrefPath("SuperTux", "supertux2") << "/console.err"; FileSystem::open_path(stream.str()); From 5260e65da0e9bc7df6386da7fd5881a775b544cf Mon Sep 17 00:00:00 2001 From: Vankata453 <78196474+Vankata453@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:07:41 +0300 Subject: [PATCH 4/5] Error handler: Properly print fatal exceptions to command line Makes the error handler print fatal exceptions to the command line, as well as reverts commits eacdc116584b93cf78d456d27893c8c6a9ab0119 and 2d929412210765aa81ab417ecbf09703ffccc0e8, which make the exception message not print out on the dialog. --- src/supertux/error_handler.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/supertux/error_handler.cpp b/src/supertux/error_handler.cpp index 8ba48b38309..82dc03d05b7 100644 --- a/src/supertux/error_handler.cpp +++ b/src/supertux/error_handler.cpp @@ -290,9 +290,18 @@ ErrorHandler::error_dialog_crash(const std::string& stacktrace) void ErrorHandler::error_dialog_exception(const std::string& exception) { - char msg[] = "SuperTux has encountered a fatal exception!"; + std::stringstream stream; - std::cerr << msg << "\n\n" << exception << std::endl; + stream << "SuperTux has encountered a fatal exception!"; + + if (!exception.empty()) + { + stream << "\n\n" << exception; + } + + std::string msg = stream.str(); + + std::cerr << msg << std::endl; SDL_MessageBoxButtonData btns[] = { #ifdef WIN32 @@ -313,7 +322,7 @@ ErrorHandler::error_dialog_exception(const std::string& exception) SDL_MESSAGEBOX_ERROR, // flags nullptr, // window "Error", // title - msg, // message + msg.c_str(), // message SDL_arraysize(btns), // numbuttons btns, // buttons nullptr // colorscheme @@ -325,7 +334,9 @@ ErrorHandler::error_dialog_exception(const std::string& exception) #ifdef WIN32 if (resultbtn == 0) { - std::stringstream stream; + // Repurpose the stream. + stream.str(""); + stream << SDL_GetPrefPath("SuperTux", "supertux2") << "/console.err"; FileSystem::open_path(stream.str()); From aee3fc716885821e8caf55ad1f21e861432631a6 Mon Sep 17 00:00:00 2001 From: Tobias Markus Date: Fri, 16 Aug 2024 00:47:31 +0200 Subject: [PATCH 5/5] Add more convenience functions to Player class (#3037) Co-authored-by: Marty <85036874+MatusGuy@users.noreply.github.com> --- src/badguy/dispenser.cpp | 2 +- src/object/camera.cpp | 4 ++-- src/object/level_time.cpp | 4 ++-- src/object/player.cpp | 16 ++++++++-------- src/object/player.hpp | 12 ++++++++++++ src/supertux/game_session.cpp | 8 ++++---- src/supertux/sector.cpp | 2 +- 7 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/badguy/dispenser.cpp b/src/badguy/dispenser.cpp index 71efb37dc0a..a21ede580bc 100644 --- a/src/badguy/dispenser.cpp +++ b/src/badguy/dispenser.cpp @@ -149,7 +149,7 @@ Dispenser::active_update(float dt_sec) auto player = get_nearest_player(); if (player) { - if(player->is_dying() || player->is_dead()) + if(!player->is_alive()) { return; } diff --git a/src/object/camera.cpp b/src/object/camera.cpp index 65ed00eb89d..13dabd4276a 100644 --- a/src/object/camera.cpp +++ b/src/object/camera.cpp @@ -572,7 +572,7 @@ Camera::update_scroll_normal_multiplayer(float dt_sec) for (const auto* p : Sector::get().get_players()) { - if (p->is_dead() || p->is_dying()) + if (!p->is_alive()) continue; float lft = p->get_bbox().get_left() - HORIZONTAL_MARGIN; @@ -636,7 +636,7 @@ Camera::update_scroll_normal_multiplayer(float dt_sec) void Camera::update_scroll_autoscroll(float dt_sec) { - if (!get_parent()->get_object_count([](const Player& p) { return !p.is_dead() && !p.is_dying(); })) + if (!get_parent()->get_object_count([](const Player& p) { return p.is_alive(); })) return; get_walker()->update(dt_sec); diff --git a/src/object/level_time.cpp b/src/object/level_time.cpp index ea7449ad649..51a0f7a46e9 100644 --- a/src/object/level_time.cpp +++ b/src/object/level_time.cpp @@ -63,7 +63,7 @@ LevelTime::update(float dt_sec) if (!running) return; int players_alive = Sector::current() ? Sector::current()->get_object_count([](const Player& p) { - return !p.is_dead() && !p.is_dying() && !p.is_winning(); + return p.is_active(); }) : 0; if (!players_alive) @@ -89,7 +89,7 @@ LevelTime::update(float dt_sec) { for (auto& p : Sector::get().get_players()) { - if (p->is_dead() || p->is_dying() || p->is_winning()) + if (!p->is_active()) continue; p->add_coins(-1); diff --git a/src/object/player.cpp b/src/object/player.cpp index b3f503ed1d2..168a2a35244 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -413,10 +413,10 @@ Player::update(float dt_sec) } // Skip if in multiplayer respawn - if (is_dead() && m_target && Sector::get().get_object_count([this](const Player& p) { return !p.is_dead() && !p.is_dying() && !p.is_winning() && &p != this; })) + if (is_dead() && m_target && Sector::get().get_object_count([this](const Player& p) { return p.is_active() && &p != this; })) { auto* target = Sector::get().get_object_by_uid(*m_target); - if (!target || target->is_dying() || target->is_dead() || target->is_winning()) + if (!target || !target->is_active()) { next_target(); } @@ -545,7 +545,7 @@ Player::update(float dt_sec) set_bonus(NO_BONUS, true); m_dead = true; - if (!Sector::get().get_object_count([](const Player& p) { return !p.is_dead() && !p.is_dying(); })) + if (!Sector::get().get_object_count([](const Player& p) { return p.is_alive(); })) { Sector::get().stop_looping_sounds(); } @@ -1992,7 +1992,7 @@ Player::draw(DrawingContext& context) if(Editor::is_active()) return; - if (is_dead() && m_target && Sector::get().get_object_count([this](const Player& p){ return !p.is_dead() && !p.is_dying() && !p.is_winning() && &p != this; })) + if (is_dead() && m_target && Sector::get().get_object_count([this](const Player& p){ return p.is_active() && &p != this; })) { auto* target = Sector::get().get_object_by_uid(*m_target); if (target) @@ -2463,7 +2463,7 @@ Player::kill(bool completely) m_dying_timer.start(3.0); set_group(COLGROUP_DISABLED); - auto alive_players = Sector::get().get_object_count([](const Player& p){ return !p.is_dead() && !p.is_dying(); }); + auto alive_players = Sector::get().get_object_count([](const Player& p){ return p.is_alive(); }); if (!alive_players) { @@ -2539,7 +2539,7 @@ Player::check_bounds() } // If Tux is swimming, don't allow him to go below the sector - if (m_swimming && !m_ghost_mode && !is_dying() && !is_dead() + if (m_swimming && !m_ghost_mode && is_alive() && m_col.m_bbox.get_bottom() > Sector::get().get_height()) { m_col.set_pos(Vector(m_col.m_bbox.get_left(), Sector::get().get_height() - m_col.m_bbox.get_height())); @@ -2910,7 +2910,7 @@ Player::next_target() bool is_next = false; for (auto* player : players) { - if (!player->is_dead() && !player->is_dying() && !player->is_winning()) + if (player->is_active()) { if (!first) { @@ -2950,7 +2950,7 @@ Player::prev_target() Player* last = nullptr; for (auto* player : players) { - if (!player->is_dead() && !player->is_dying() && !player->is_winning()) + if (player->is_active()) { if (m_target && player->get_uid() == *m_target && last) { diff --git a/src/object/player.hpp b/src/object/player.hpp index fa78b451647..720ec781949 100644 --- a/src/object/player.hpp +++ b/src/object/player.hpp @@ -135,6 +135,18 @@ class Player final : public MovingObject bool is_invincible() const { return m_invincible_timer.started(); } bool is_dying() const { return m_dying; } + /** + * Returns true if the player is currently alive + * (not dying or dead) + */ + bool is_alive() const { return !is_dying() && !is_dead(); } + + /** + * Returns true if the player can be controlled. + * (alive and not currently in a win sequence) + */ + bool is_active() const { return is_alive() && !is_winning(); } + Direction peeking_direction_x() const { return m_peekingX; } Direction peeking_direction_y() const { return m_peekingY; } diff --git a/src/supertux/game_session.cpp b/src/supertux/game_session.cpp index ce9ff0d6285..3a602556e7b 100644 --- a/src/supertux/game_session.cpp +++ b/src/supertux/game_session.cpp @@ -267,7 +267,7 @@ GameSession::on_escape_press(bool force_quick_respawn) auto players = m_currentsector->get_players(); int alive = m_currentsector->get_object_count([](const Player& p) { - return !p.is_dead() && !p.is_dying(); + return p.is_alive(); }); if ((!alive && (m_play_time > 2.0f || force_quick_respawn)) || m_end_sequence) @@ -336,7 +336,7 @@ GameSession::get_fade_point(const Vector& position) const for (const auto* player : m_currentsector->get_players()) { - if (!player->is_dead() && !player->is_dying()) + if (player->is_alive()) { average_position += player->get_bbox().get_middle(); alive_players++; @@ -417,7 +417,7 @@ GameSession::check_end_conditions() bool all_dead_or_winning = true; for (const auto* p : m_currentsector->get_players()) - if (!(all_dead_or_winning &= (p->is_dead() || p->is_dying() || p->is_winning()))) + if (!(all_dead_or_winning &= (!p->is_active()))) break; /* End of level? */ @@ -861,7 +861,7 @@ GameSession::start_sequence(Player* caller, Sequence seq, const SequenceData* da caller->set_winning(); int remaining_players = get_current_sector().get_object_count([](const Player& p){ - return !p.is_dead() && !p.is_dying() && !p.is_winning(); + return p.is_active(); }); // Abort if a sequence is already playing. diff --git a/src/supertux/sector.cpp b/src/supertux/sector.cpp index 672d3f11f6b..62ef6224e5d 100644 --- a/src/supertux/sector.cpp +++ b/src/supertux/sector.cpp @@ -728,7 +728,7 @@ Sector::get_nearest_player (const Vector& pos) const for (auto player_ptr : get_objects_by_type_index(typeid(Player))) { Player& player = *static_cast(player_ptr); - if (player.is_dying() || player.is_dead()) + if (!player.is_alive()) continue; float dist = player.get_bbox ().distance(pos);