diff --git a/data/scripts/default.nut b/data/scripts/default.nut index 7f674e51c47..082c35831cc 100644 --- a/data/scripts/default.nut +++ b/data/scripts/default.nut @@ -13,6 +13,8 @@ Level <- { set_respawn_pos=Level_set_respawn_pos, flip_vertically=Level_flip_vertically, toggle_pause=Level_toggle_pause, + pause_target_timer=Level_pause_target_timer, + resume_target_timer=Level_resume_target_timer, edit=Level_edit }; diff --git a/src/scripting/level.cpp b/src/scripting/level.cpp index 184fe5532c2..f513ccc07f8 100644 --- a/src/scripting/level.cpp +++ b/src/scripting/level.cpp @@ -86,6 +86,20 @@ Level_edit(bool edit_mode) game_session.set_editmode(edit_mode); } +void +Level_pause_target_timer() +{ + SCRIPT_GUARD_GAMESESSION; + game_session.set_target_timer_paused(true); +} + +void +Level_resume_target_timer() +{ + SCRIPT_GUARD_GAMESESSION; + game_session.set_target_timer_paused(false); +} + } // namespace scripting /* EOF */ diff --git a/src/scripting/level.hpp b/src/scripting/level.hpp index 970631c8f59..a35e1dafc15 100644 --- a/src/scripting/level.hpp +++ b/src/scripting/level.hpp @@ -109,6 +109,16 @@ void Level_toggle_pause(); */ void Level_edit(bool edit_mode); +/** + * Pauses the target timer. + */ +void Level_pause_target_timer(); + +/** + * Resumes the target timer. + */ +void Level_resume_target_timer(); + #ifdef DOXYGEN_SCRIPTING } #endif diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index e61e5653580..14f9e9de1d8 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -12471,6 +12471,44 @@ static SQInteger Level_edit_wrapper(HSQUIRRELVM vm) } +static SQInteger Level_pause_target_timer_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + scripting::Level_pause_target_timer(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_pause_target_timer'")); + return SQ_ERROR; + } + +} + +static SQInteger Level_resume_target_timer_wrapper(HSQUIRRELVM vm) +{ + (void) vm; + + try { + scripting::Level_resume_target_timer(); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_resume_target_timer'")); + return SQ_ERROR; + } + +} + } // namespace wrapper void create_squirrel_instance(HSQUIRRELVM v, scripting::AmbientSound* object, bool setup_releasehook) { @@ -13747,6 +13785,20 @@ void register_supertux_wrapper(HSQUIRRELVM v) throw SquirrelError(v, "Couldn't register function 'Level_edit'"); } + sq_pushstring(v, "Level_pause_target_timer", -1); + sq_newclosure(v, &Level_pause_target_timer_wrapper, 0); + sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "."); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'Level_pause_target_timer'"); + } + + sq_pushstring(v, "Level_resume_target_timer", -1); + sq_newclosure(v, &Level_resume_target_timer_wrapper, 0); + sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "."); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'Level_resume_target_timer'"); + } + // Register class AmbientSound sq_pushstring(v, "AmbientSound", -1); if(sq_newclass(v, SQFalse) < 0) { diff --git a/src/supertux/game_session.cpp b/src/supertux/game_session.cpp index 1b8ec5af3a9..83ac9159592 100644 --- a/src/supertux/game_session.cpp +++ b/src/supertux/game_session.cpp @@ -75,6 +75,7 @@ GameSession::GameSession(const std::string& levelfile_, Savegame& savegame, Stat m_max_ice_bullets_at_start(), m_active(false), m_end_seq_started(false), + m_pause_target_timer(false), m_current_cutscene_text(), m_endsequence_timer() { @@ -110,6 +111,7 @@ GameSession::reset_level() clear_respawn_points(); m_activated_checkpoint = nullptr; + m_pause_target_timer = false; } int @@ -535,7 +537,7 @@ GameSession::update(float dt_sec, const Controller& controller) assert(m_currentsector != nullptr); // Update the world if (!m_end_sequence || !m_end_sequence->is_running()) { - if (!m_level->m_is_in_cutscene) + if (!m_level->m_is_in_cutscene && !m_pause_target_timer) { m_play_time += dt_sec; m_level->m_stats.finish(m_play_time); @@ -824,11 +826,21 @@ GameSession::start_sequence(Player* caller, Sequence seq, const SequenceData* da } // Stop all clocks. - for (const auto& obj : m_currentsector->get_objects()) + for (LevelTime& lt : m_currentsector->get_objects_by_type()) { - auto lt = dynamic_cast(obj.get()); - if (lt) - lt->stop(); + lt.stop(); + } +} +void +GameSession::set_target_timer_paused(bool paused) +{ + m_pause_target_timer = paused; + for (LevelTime& lt : m_currentsector->get_objects_by_type()) + { + if(paused) + lt.stop(); + else + lt.start(); } } diff --git a/src/supertux/game_session.hpp b/src/supertux/game_session.hpp index da569a7b5f9..75ed63dd953 100644 --- a/src/supertux/game_session.hpp +++ b/src/supertux/game_session.hpp @@ -107,6 +107,7 @@ class GameSession final : public Screen, Level& get_current_level() const { return *m_level; } void start_sequence(Player* caller, Sequence seq, const SequenceData* data = nullptr); + void set_target_timer_paused(bool paused); /** * returns the "working directory" usually this is the directory where the @@ -187,6 +188,7 @@ class GameSession final : public Screen, bool m_active; /** Game active? **/ bool m_end_seq_started; + bool m_pause_target_timer; std::unique_ptr m_current_cutscene_text;