// hud_calculate_lock_position() will determine where on the screen to draw the lock // indicator, and will determine when a lock has occurred. If the lock indicator is not // on the screen yet, hud_calculate_lock_start_pos() is called to pick a starting location void hud_calculate_lock_position(float frametime) { ship_weapon *swp; weapon_info *wip; static float pixels_moved_while_locking; static float pixels_moved_while_degrading; static int Need_new_start_pos = 0; static double accumulated_x_pixels, accumulated_y_pixels; double int_portion; static float last_dist_to_target; static int catching_up; static int maintain_lock_count = 0; static float catch_up_distance = 0.0f; double hypotenuse, delta_x, delta_y; swp = &Player_ship->weapons; wip = &Weapon_info[swp->secondary_bank_weapons[swp->current_secondary_bank]]; if (Player->target_in_lock_cone) { if (!Players[Player_num].lock_indicator_visible) { hud_calculate_lock_start_pos(); last_dist_to_target = 0.0f; Players[Player_num].lock_indicator_x = Players[Player_num].lock_indicator_start_x; Players[Player_num].lock_indicator_y = Players[Player_num].lock_indicator_start_y; Players[Player_num].lock_indicator_visible = 1; Players[Player_num].lock_time_to_target = i2fl(wip->min_lock_time); catching_up = 0; } Need_new_start_pos = 1; if (Player_ai->current_target_is_locked) { Players[Player_num].lock_indicator_x = Player->current_target_sx; Players[Player_num].lock_indicator_y = Player->current_target_sy; return; } delta_x = Players[Player_num].lock_indicator_x - Player->current_target_sx; delta_y = Players[Player_num].lock_indicator_y - Player->current_target_sy; if (!delta_y && !delta_x) { hypotenuse = 0.0f; } else { hypotenuse = _hypot(delta_y, delta_x); } Players[Player_num].lock_dist_to_target = (float)hypotenuse; if (last_dist_to_target == 0) { last_dist_to_target = Players[Player_num].lock_dist_to_target; } //nprintf(("Alan","dist to target: %.2f\n",Players[Player_num].lock_dist_to_target)); //nprintf(("Alan","last to target: %.2f\n\n",last_dist_to_target)); if (catching_up) { //nprintf(("Alan","IN CATCH UP MODE catch_up_dist is %.2f\n",catch_up_distance)); if ( Players[Player_num].lock_dist_to_target < catch_up_distance ) catching_up = 0; } else { //nprintf(("Alan","IN NORMAL MODE\n")); if ( (Players[Player_num].lock_dist_to_target - last_dist_to_target) > 2.0f ) { catching_up = 1; catch_up_distance = last_dist_to_target + wip->catchup_pixel_penalty; } } last_dist_to_target = Players[Player_num].lock_dist_to_target; if (!catching_up) { Players[Player_num].lock_time_to_target -= frametime; if (Players[Player_num].lock_time_to_target < 0.0f) Players[Player_num].lock_time_to_target = 0.0f; } float lock_pixels_per_sec; if (Players[Player_num].lock_time_to_target > 0) { lock_pixels_per_sec = Players[Player_num].lock_dist_to_target / Players[Player_num].lock_time_to_target; } else { lock_pixels_per_sec = i2fl(wip->lock_pixels_per_sec); } if (lock_pixels_per_sec > wip->lock_pixels_per_sec) { lock_pixels_per_sec = i2fl(wip->lock_pixels_per_sec); } if (catching_up) { pixels_moved_while_locking = wip->catchup_pixels_per_sec * frametime; } else { pixels_moved_while_locking = lock_pixels_per_sec * frametime; } if (delta_x != 0) { accumulated_x_pixels += pixels_moved_while_locking * delta_x/hypotenuse; } if (delta_y != 0) { accumulated_y_pixels += pixels_moved_while_locking * delta_y/hypotenuse; } if (fl_abs(accumulated_x_pixels) > 1.0f) { modf(accumulated_x_pixels, &int_portion); Players[Player_num].lock_indicator_x -= (int)int_portion; if ( fl_abs(Players[Player_num].lock_indicator_x - Player->current_target_sx) < fl_abs(int_portion) ) Players[Player_num].lock_indicator_x = Player->current_target_sx; accumulated_x_pixels -= int_portion; } if (fl_abs(accumulated_y_pixels) > 1.0f) { modf(accumulated_y_pixels, &int_portion); Players[Player_num].lock_indicator_y -= (int)int_portion; if ( fl_abs(Players[Player_num].lock_indicator_y - Player->current_target_sy) < fl_abs(int_portion) ) Players[Player_num].lock_indicator_y = Player->current_target_sy; accumulated_y_pixels -= int_portion; } if ( Missile_track_loop == -1 ) { Missile_track_loop = snd_play_looping( &Snds[SND_MISSILE_TRACKING], 0.0f , -1, -1); } if (!Players[Player_num].lock_time_to_target) { if ( (Players[Player_num].lock_indicator_x == Player->current_target_sx) && (Players[Player_num].lock_indicator_y == Player->current_target_sy) ) { if (maintain_lock_count++ > 1) { Player_ai->current_target_is_locked = 1; } } else { maintain_lock_count = 0; } } } else { if ( Missile_track_loop > -1 ) { snd_chg_loop_status(Missile_track_loop, 0); Missile_track_loop = -1; } Player_ai->current_target_is_locked = 0; if (!Players[Player_num].lock_indicator_visible) { return; } catching_up = 0; last_dist_to_target = 0.0f; if (Need_new_start_pos) { hud_calculate_lock_start_pos(); Need_new_start_pos = 0; accumulated_x_pixels = 0.0f; accumulated_y_pixels = 0.0f; } delta_x = Players[Player_num].lock_indicator_x - Players[Player_num].lock_indicator_start_x; delta_y = Players[Player_num].lock_indicator_y - Players[Player_num].lock_indicator_start_y; if (!delta_y && !delta_x) { hypotenuse = 0.0f; } else { hypotenuse = _hypot(delta_y, delta_x); } Players[Player_num].lock_time_to_target += frametime; if (Players[Player_num].lock_time_to_target > wip->min_lock_time) Players[Player_num].lock_time_to_target = i2fl(wip->min_lock_time); pixels_moved_while_degrading = 2.0f * wip->lock_pixels_per_sec * frametime; if (delta_x != 0) accumulated_x_pixels += pixels_moved_while_degrading * delta_x/hypotenuse; if (delta_y != 0) accumulated_y_pixels += pixels_moved_while_degrading * delta_y/hypotenuse; if (fl_abs(accumulated_x_pixels) > 1.0f) { modf(accumulated_x_pixels, &int_portion); Players[Player_num].lock_indicator_x -= (int)int_portion; if ( fl_abs(Players[Player_num].lock_indicator_x - Players[Player_num].lock_indicator_start_x) < fl_abs(int_portion) ) Players[Player_num].lock_indicator_x = Players[Player_num].lock_indicator_start_x; accumulated_x_pixels -= int_portion; } if (fl_abs(accumulated_y_pixels) > 1.0f) { modf(accumulated_y_pixels, &int_portion); Players[Player_num].lock_indicator_y -= (int)int_portion; if ( fl_abs(Players[Player_num].lock_indicator_y - Players[Player_num].lock_indicator_start_y) < fl_abs(int_portion) ) Players[Player_num].lock_indicator_y = Players[Player_num].lock_indicator_start_y; accumulated_y_pixels -= int_portion; } if ( (Players[Player_num].lock_indicator_x == Players[Player_num].lock_indicator_start_x) && (Players[Player_num].lock_indicator_y == Players[Player_num].lock_indicator_start_y) ) { Players[Player_num].lock_indicator_visible = 0; } } }
void radar_frame_render(float frametime) { float sensors_str; int ok_to_blit_radar; ok_to_blit_radar = 1; sensors_str = ship_get_subsystem_strength( Player_ship, SUBSYSTEM_SENSORS ); if ( ship_subsys_disrupted(Player_ship, SUBSYSTEM_SENSORS) ) { sensors_str = MIN_SENSOR_STR_TO_RADAR-1; } // note that on lowest skill level, there is no radar effects due to sensors damage if ( (Game_skill_level == 0) || (sensors_str > SENSOR_STR_RADAR_NO_EFFECTS) ) { Radar_static_playing = 0; Radar_static_next = 0; Radar_death_timer = 0; Radar_avail_prev_frame = 1; } else if ( sensors_str < MIN_SENSOR_STR_TO_RADAR ) { if ( Radar_avail_prev_frame ) { Radar_death_timer = timestamp(2000); Radar_static_next = 1; } Radar_avail_prev_frame = 0; } else { Radar_death_timer = 0; if ( Radar_static_next == 0 ) Radar_static_next = 1; } if ( timestamp_elapsed(Radar_death_timer) ) { ok_to_blit_radar = 0; } hud_set_gauge_color(HUD_RADAR); radar_blit_gauge(); radar_draw_range(); if ( timestamp_elapsed(Radar_static_next) ) { Radar_static_playing ^= 1; Radar_static_next = timestamp_rand(50, 750); } // if the emp effect is active, always draw the radar wackily if(emp_active_local()){ Radar_static_playing = 1; } if ( ok_to_blit_radar ) { if ( Radar_static_playing ) { radar_draw_blips_sorted(1); // passing 1 means to draw distorted if ( Radar_static_looping == -1 ) { Radar_static_looping = snd_play_looping(&Snds[SND_STATIC]); } } else { radar_draw_blips_sorted(); if ( Radar_static_looping != -1 ) { snd_stop(Radar_static_looping); Radar_static_looping = -1; } } } else { if ( Radar_static_looping != -1 ) { snd_stop(Radar_static_looping); Radar_static_looping = -1; } } }
// ---------------------------------------------------------------------------- // afterburners_update() // // Update the state of the afterburner fuel remaining for an object using the // afterburner. // // for the player ship, key_up_time() is called for the afterburner key to // detect when afterburners disengage. // // input: *objp => pointer to the object starting afterburners // fl_frametime => time in seconds of the last frame // void afterburners_update(object* objp, float fl_frametime) { Assert(objp != NULL); Assert(objp->type == OBJ_SHIP); Assert(objp->instance >= 0 && objp->instance < MAX_SHIPS); ship_info* sip; ship* shipp; static int volume_chg_timer = 1; shipp = &Ships[objp->instance]; Assert(shipp->ship_info_index >= 0 && shipp->ship_info_index < Num_ship_classes); sip = &Ship_info[shipp->ship_info_index]; if ((objp->flags & OF_PLAYER_SHIP) && (Game_mode & GM_DEAD)) { return; } if (!(sip->flags & SIF_AFTERBURNER)) { return; // nothing to update, afterburners are not even on the ship } //shut the afterburners off if we're using the booster tertiary //shut the afterburners off if we're in glide mode. if ((objp->phys_info.flags & PF_AFTERBURNER_ON) && ((objp->phys_info.flags & PF_BOOSTER_ON) || (objp->phys_info.flags & PF_GLIDING))) { if (objp == Player_obj) afterburner_stop_sounds(); afterburners_stop(objp); return; } if (objp == Player_obj) { if (!timestamp_elapsed(Player_disengage_timer)) { float remaining; remaining = timestamp_until(Player_disengage_timer) / i2fl(DISENGAGE_TIME); if (remaining <= 0) { afterburner_stop_sounds(); } else { if (remaining > 1.0f) { remaining = 1.0f; } snd_set_volume(Player_afterburner_loop_id, remaining * Player_afterburner_vol); } } else { if (Player_disengage_timer != 1) { afterburner_stop_sounds(); } } } // single player, multiplayer servers, and clients for their own ships if (!(Game_mode & GM_MULTIPLAYER) || MULTIPLAYER_MASTER || (objp == Player_obj)) { if (!(objp->phys_info.flags & PF_AFTERBURNER_ON)) { // Recover afterburner fuel if (shipp->afterburner_fuel < sip->afterburner_fuel_capacity) { float recharge_scale; recharge_scale = Energy_levels[shipp->engine_recharge_index] * 2.0f * The_mission.ai_profile-> afterburner_recharge_scale[Game_skill_level]; shipp->afterburner_fuel += (sip->afterburner_recover_rate * fl_frametime * recharge_scale); if (shipp->afterburner_fuel > sip->afterburner_fuel_capacity) { shipp->afterburner_fuel = sip->afterburner_fuel_capacity; } } return; } else { // Check if there is enough afterburner fuel if (shipp->afterburner_fuel <= 0) { shipp->afterburner_fuel = 0.0f; afterburners_stop(objp); return; } } // afterburners are firing at this point // Reduce the afterburner fuel shipp->afterburner_fuel -= (sip->afterburner_burn_rate * fl_frametime); if (shipp->afterburner_fuel < 0.0f) { shipp->afterburner_fuel = 0.0f; } } if (objp == Player_obj) { if ((Viewer_mode & VM_NOT_COCKPIT)) { // stop afterburner sound if it is playing if (Player_afterburner_loop_id != -1) { snd_stop(Player_afterburner_loop_id); Player_afterburner_loop_id = -1; } return; } if (timestamp_elapsed(Player_afterburner_loop_delay)) { Player_afterburner_vol = Snds[SND_ABURN_LOOP].default_volume; Player_afterburner_loop_delay = timestamp(50); if (Player_afterburner_loop_id == -1) { Player_afterburner_loop_id = snd_play_looping(&Snds[SND_ABURN_LOOP], 0.0f, -1, -1, Player_afterburner_vol); //snd_set_volume(Player_afterburner_loop_id, Player_afterburner_vol); // nprintf(("Alan","PLAY LOOPING SOUND\n")); } } // Reduce the volume of the afterburner sound if near the end if (timestamp_elapsed(volume_chg_timer)) { float percent_afterburner_left; percent_afterburner_left = shipp->afterburner_fuel / sip->afterburner_fuel_capacity; volume_chg_timer = timestamp(AFTERBURNER_VOLUME_UPDATE); if (percent_afterburner_left < AFTERBURNER_PERCENT_VOL_ATTENUATE) { Player_afterburner_vol = percent_afterburner_left * (1 / AFTERBURNER_PERCENT_VOL_ATTENUATE) * Snds[SND_ABURN_LOOP].default_volume; snd_set_volume(Player_afterburner_loop_id, Player_afterburner_vol); } } // end if (timestamp_elapsed(volume_chg_timer)) } }
void HudGaugeRadarDradis::render(float frametime) { float sensors_str; int ok_to_blit_radar; ok_to_blit_radar = 1; sensors_str = ship_get_subsystem_strength(Player_ship, SUBSYSTEM_SENSORS); if (ship_subsys_disrupted(Player_ship, SUBSYSTEM_SENSORS)) sensors_str = MIN_SENSOR_STR_TO_RADAR - 1; // note that on lowest skill level, there is no radar effects due to sensors damage if ((Game_skill_level == 0) || (sensors_str > SENSOR_STR_RADAR_NO_EFFECTS)) { Radar_static_playing = 0; Radar_static_next = 0; Radar_death_timer = 0; Radar_avail_prev_frame = 1; } else if (sensors_str < MIN_SENSOR_STR_TO_RADAR) { if (Radar_avail_prev_frame) { Radar_death_timer = timestamp(2000); Radar_static_next = 1; } Radar_avail_prev_frame = 0; } else { Radar_death_timer = 0; if (Radar_static_next == 0) Radar_static_next = 1; } if (timestamp_elapsed(Radar_death_timer)) ok_to_blit_radar = 0; setupViewHtl(); //WMC - This strikes me as a bit hackish bool g3_yourself = !g3_in_frame(); if(g3_yourself) g3_start_frame(1); drawSweeps(); if (timestamp_elapsed(Radar_static_next)) { Radar_static_playing ^= 1; Radar_static_next = timestamp_rand(50, 750); } // if the emp effect is active, always draw the radar wackily if (emp_active_local()) Radar_static_playing = 1; if (ok_to_blit_radar) { if (Radar_static_playing) { drawBlipsSorted(1); // passing 1 means to draw distorted if (Radar_static_looping == -1) Radar_static_looping = snd_play_looping(&Snds[SND_STATIC]); } else { drawBlipsSorted(0); if (Radar_static_looping != -1) { snd_stop(Radar_static_looping); Radar_static_looping = -1; } } } else { if (Radar_static_looping != -1) { snd_stop(Radar_static_looping); Radar_static_looping = -1; } } if(g3_yourself) g3_end_frame(); doneDrawingHtl(); }
/** * Update the state of the afterburner fuel remaining for an object using the afterburner. * * For the player ship, key_up_time() is called for the afterburner key to * detect when afterburners disengage. * * @param *objp pointer to the object starting afterburners * @param fl_frametime time in seconds of the last frame */ void afterburners_update(object *objp, float fl_frametime) { Assert( objp != NULL ); Assert( objp->type == OBJ_SHIP ); Assert( objp->instance >= 0 && objp->instance < MAX_SHIPS ); ship_info *sip; ship *shipp; static int volume_chg_timer = 1; shipp = &Ships[objp->instance]; Assert( shipp->ship_info_index >= 0 && shipp->ship_info_index < static_cast<int>(Ship_info.size()) ); sip = &Ship_info[shipp->ship_info_index]; if ( (objp->flags[Object::Object_Flags::Player_ship] ) && (Game_mode & GM_DEAD) ) { return; } if ( !(sip->flags[Ship::Info_Flags::Afterburner]) ) { return; // nothing to update, afterburners are not even on the ship } //shut the afterburners off if we're using the booster tertiary if ( objp->phys_info.flags & PF_BOOSTER_ON) { if (objp==Player_obj) afterburner_stop_sounds(); afterburners_stop(objp); return; } if ( objp == Player_obj ) { if ( !timestamp_elapsed(Player_disengage_timer) ) { float remaining; remaining = timestamp_until(Player_disengage_timer) / i2fl(DISENGAGE_TIME); if ( remaining <= 0 ) { afterburner_stop_sounds(); } else { snd_set_volume( Player_afterburner_loop_id, remaining*Player_afterburner_vol); } } else { if ( Player_disengage_timer != 1 ) { afterburner_stop_sounds(); } } } // single player, multiplayer servers, and clients for their own ships if(!(Game_mode & GM_MULTIPLAYER) || MULTIPLAYER_MASTER || (objp == Player_obj)) { if ( !(objp->phys_info.flags & PF_AFTERBURNER_ON) ) { // Recover afterburner fuel if ( shipp->afterburner_fuel < sip->afterburner_fuel_capacity ) { float recharge_scale; recharge_scale = Energy_levels[shipp->engine_recharge_index] * 2.0f * The_mission.ai_profile->afterburner_recharge_scale[Game_skill_level]; shipp->afterburner_fuel += (sip->afterburner_recover_rate * fl_frametime * recharge_scale); if ( shipp->afterburner_fuel > sip->afterburner_fuel_capacity){ shipp->afterburner_fuel = sip->afterburner_fuel_capacity; } } return; } else { // Check if there is enough afterburner fuel if ( shipp->afterburner_fuel <= 0 ) { shipp->afterburner_fuel = 0.0f; afterburners_stop(objp); return; } } // afterburners are firing at this point // Reduce the afterburner fuel shipp->afterburner_fuel -= (sip->afterburner_burn_rate * fl_frametime); if ( shipp->afterburner_fuel < 0.0f ) { shipp->afterburner_fuel = 0.0f; } } if ( objp == Player_obj ) { if ( timestamp_elapsed(Player_afterburner_loop_delay) ) { Player_afterburner_vol = AFTERBURNER_DEFAULT_VOL; Player_afterburner_loop_delay = 0; if ( Player_afterburner_loop_id == -1 ) { Player_afterburner_loop_id = snd_play_looping( gamesnd_get_game_sound(ship_get_sound(objp, GameSounds::ABURN_LOOP)), 0.0f , -1, -1); snd_set_volume(Player_afterburner_loop_id, Player_afterburner_vol); } } // Reduce the volume of the afterburner sound if near the end if ( timestamp_elapsed(volume_chg_timer) ) { float percent_afterburner_left; percent_afterburner_left = shipp->afterburner_fuel / sip->afterburner_fuel_capacity; volume_chg_timer = timestamp(AFTERBURNER_VOLUME_UPDATE); if ( percent_afterburner_left < AFTERBURNER_PERCENT_VOL_ATTENUATE ) { Player_afterburner_vol = percent_afterburner_left*(1/AFTERBURNER_PERCENT_VOL_ATTENUATE)*AFTERBURNER_DEFAULT_VOL; snd_set_volume(Player_afterburner_loop_id, Player_afterburner_vol); } } // end if (timestamp_elapsed(volume_chg_timer)) } }