From 72360677906709175302a008e700c2ffbc97715e Mon Sep 17 00:00:00 2001 From: btawaifi Date: Sat, 17 Oct 2026 23:08:09 +0300 Subject: [PATCH] Measure afterburner cooldowns on the mission clock afterburners_start()/afterburners_stop() timed the +Aburn Cooldown Time delay and the player's 1.3 s re-engage delay with timer_get_milliseconds(), the real clock. Under time compression a cooldown therefore lasted longer in mission time than the table says, and it kept running while the game was paused. The cooldown was added in 2020 and reused the retail re-engage check's real-clock "now"; the rest of the file (ABURN_DECAY_TIME, the sound timers) already uses mission timestamps. Both delays now use the mission clock. The mission clock does not run outside missions, so it can still be near zero when the first mission of a session starts; the "last stopped" and "last started" times therefore start out invalid instead of 0, so that no delay is in effect before the afterburner has been used. Without time compression or pausing, the delays behave as before. --- code/ship/afterburner.cpp | 16 ++++++++-------- code/ship/ship.cpp | 2 +- code/ship/ship.h | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/code/ship/afterburner.cpp b/code/ship/afterburner.cpp index 2860e61769f..f7134909809 100644 --- a/code/ship/afterburner.cpp +++ b/code/ship/afterburner.cpp @@ -29,7 +29,7 @@ static sound_handle Player_afterburner_loop_id; // identifies the looping afterb static int Player_afterburner_loop_delay; // timestamp used to time the start of the looping afterburner sound static int Player_disengage_timer; static float Player_afterburner_vol; -static int Player_afterburner_start_time; +static TIMESTAMP Player_afterburner_start_time; // ---------------------------------------------------------- @@ -53,7 +53,7 @@ void afterburner_level_init() Player_disengage_timer = 1; Player_afterburner_vol = AFTERBURNER_DEFAULT_VOL; Player_afterburner_loop_id = sound_handle::invalid(); - Player_afterburner_start_time = 0; + Player_afterburner_start_time = TIMESTAMP::invalid(); } /** @@ -88,9 +88,9 @@ void afterburners_start(object *objp) shipp->flags.set(Ship::Ship_Flags::Attempting_to_afterburn); - int now = timer_get_milliseconds(); - - if (now - shipp->afterburner_last_end_time < (int)(sip->afterburner_cooldown_time * 1000.0f)) { + // Measured in mission time, so the delays last as long as specified under time compression or a pause. + // They start invalid, because the mission clock may still be near zero when the first mission begins. + if (shipp->afterburner_last_end_time.isFinite() && timestamp_since(shipp->afterburner_last_end_time) < (int)(sip->afterburner_cooldown_time * 1000.0f)) { if ((objp->flags[Object::Object_Flags::Player_ship]) && (objp == Player_obj)) snd_play(gamesnd_get_game_sound(ship_get_sound(objp, GameSounds::ABURN_FAIL))); @@ -101,7 +101,7 @@ void afterburners_start(object *objp) if ( (objp->flags[Object::Object_Flags::Player_ship]) && (objp == Player_obj) ) { - if ( (now - Player_afterburner_start_time) < 1300 ) { + if ( Player_afterburner_start_time.isFinite() && timestamp_since(Player_afterburner_start_time) < 1300 ) { snd_play( gamesnd_get_game_sound(ship_get_sound(objp, GameSounds::ABURN_FAIL)) ); return; } @@ -143,7 +143,7 @@ void afterburners_start(object *objp) Ship_info[shipp->ship_info_index].animations.getAll(model_get_instance(shipp->model_instance_num), animation::ModelAnimationTriggerType::Afterburner).start(animation::ModelAnimationDirection::FWD); if ( objp == Player_obj ) { - Player_afterburner_start_time = timer_get_milliseconds(); + Player_afterburner_start_time = _timestamp(); Player_disengage_timer = 1; Player_afterburner_vol = AFTERBURNER_DEFAULT_VOL; @@ -330,7 +330,7 @@ void afterburners_stop(object *objp, int key_released) return; } - shipp->afterburner_last_end_time = timer_get_milliseconds(); + shipp->afterburner_last_end_time = _timestamp(); if (scripting::hooks::OnAfterburnerEnd->isActive()) { scripting::hooks::OnAfterburnerEnd->run(scripting::hooks::ShipSourceConditions{ shipp }, diff --git a/code/ship/ship.cpp b/code/ship/ship.cpp index 21f148802b5..8f0269f3ceb 100644 --- a/code/ship/ship.cpp +++ b/code/ship/ship.cpp @@ -6970,7 +6970,7 @@ void ship::clear() afterburner_fuel = 0.0f; afterburner_last_engage_fuel = 0.0f; - afterburner_last_end_time = 0; + afterburner_last_end_time = TIMESTAMP::invalid(); cmeasure_count = 0; current_cmeasure = -1; diff --git a/code/ship/ship.h b/code/ship/ship.h index 52789d22783..1a40e5157b1 100644 --- a/code/ship/ship.h +++ b/code/ship/ship.h @@ -756,7 +756,7 @@ class ship float afterburner_fuel; // amount of afterburner fuel remaining (capacity is stored // as afterburner_fuel_capacity in ship_info). float afterburner_last_engage_fuel; // the fuel level when the afterburners were last engaged - int afterburner_last_end_time; // timestamp when the ship last stopped its afterburner + TIMESTAMP afterburner_last_end_time; // when the ship last stopped its afterburner int cmeasure_count; // Number of charges of countermeasures this ship can hold. int current_cmeasure; // Currently selected countermeasure.